#ifndef _SYS_UIO_INTERNAL_H_
#define _SYS_UIO_INTERNAL_H_
#include <sys/appleapiopts.h>
#ifdef KERNEL_PRIVATE
#include <sys/uio.h>
#include <sys/malloc.h>
#define UIO_USERISPACE 1
#define UIO_PHYS_USERSPACE 3
#define UIO_PHYS_SYSSPACE 4
#define UIO_USERISPACE32 6
#define UIO_PHYS_USERSPACE32 7
#define UIO_USERISPACE64 9
#define UIO_PHYS_USERSPACE64 10
#define UIO_PHYS_SYSSPACE32 12
#define UIO_SYSSPACE64 13
#define UIO_PHYS_SYSSPACE64 14
__BEGIN_DECLS
struct user_iovec;
struct user_iovec * uio_iovsaddr( uio_t a_uio );
__private_extern__ void uio_calculateresid( uio_t a_uio );
__private_extern__ void uio_setcurriovlen( uio_t a_uio, user_size_t a_value );
int uio_spacetype( uio_t a_uio );
__private_extern__ uio_t
uio_createwithbuffer( int a_iovcount, off_t a_offset, int a_spacetype,
int a_iodirection, void *a_buf_p, int a_buffer_size );
struct kern_iovec {
u_int32_t iov_base;
u_int32_t iov_len;
};
struct user_iovec {
user_addr_t iov_base;
user_size_t iov_len;
};
#if 1 // LP64todo - remove this after kext adopt new KPI
#define uio_iov uio_iovs.iovp
#define iovec_32 kern_iovec
#define iovec_64 user_iovec
#define iov32p kiovp
#define iov64p uiovp
#endif
union iovecs {
struct iovec *iovp;
struct kern_iovec *kiovp;
struct user_iovec *uiovp;
};
struct uio {
union iovecs uio_iovs;
int uio_iovcnt;
off_t uio_offset;
int uio_resid;
enum uio_seg uio_segflg;
enum uio_rw uio_rw;
proc_t uio_procp;
user_ssize_t uio_resid_64;
int uio_size;
int uio_max_iovs;
u_int32_t uio_flags;
};
#define UIO_FLAGS_INITED 0x00000001
#define UIO_FLAGS_WE_ALLOCED 0x00000002
__END_DECLS
#define UIO_SIZEOF( a_iovcount ) \
( sizeof(struct uio) + (sizeof(struct user_iovec) * (a_iovcount)) )
#define UIO_IS_64_BIT_SPACE( a_uio_t ) \
( (a_uio_t)->uio_segflg == UIO_USERSPACE64 || (a_uio_t)->uio_segflg == UIO_USERISPACE64 || \
(a_uio_t)->uio_segflg == UIO_PHYS_USERSPACE64 || (a_uio_t)->uio_segflg == UIO_SYSSPACE64 || \
(a_uio_t)->uio_segflg == UIO_PHYS_SYSSPACE64 )
#define UIO_IS_32_BIT_SPACE( a_uio_t ) \
( (a_uio_t)->uio_segflg == UIO_USERSPACE || (a_uio_t)->uio_segflg == UIO_USERISPACE || \
(a_uio_t)->uio_segflg == UIO_SYSSPACE || (a_uio_t)->uio_segflg == UIO_PHYS_USERSPACE || \
(a_uio_t)->uio_segflg == UIO_USERISPACE32 || (a_uio_t)->uio_segflg == UIO_PHYS_USERSPACE32 || \
(a_uio_t)->uio_segflg == UIO_SYSSPACE32 || (a_uio_t)->uio_segflg == UIO_PHYS_SYSSPACE32 || \
(a_uio_t)->uio_segflg == UIO_PHYS_SYSSPACE || (a_uio_t)->uio_segflg == UIO_USERSPACE32 )
#define UIO_IS_USER_SPACE32( a_uio_t ) \
( (a_uio_t)->uio_segflg == UIO_USERSPACE32 || (a_uio_t)->uio_segflg == UIO_PHYS_USERSPACE32 || \
(a_uio_t)->uio_segflg == UIO_USERISPACE32 )
#define UIO_IS_USER_SPACE64( a_uio_t ) \
( (a_uio_t)->uio_segflg == UIO_USERSPACE64 || (a_uio_t)->uio_segflg == UIO_PHYS_USERSPACE64 || \
(a_uio_t)->uio_segflg == UIO_USERISPACE64 )
#define UIO_IS_USER_SPACE( a_uio_t ) \
( UIO_IS_USER_SPACE32((a_uio_t)) || UIO_IS_USER_SPACE64((a_uio_t)) || \
(a_uio_t)->uio_segflg == UIO_USERSPACE || (a_uio_t)->uio_segflg == UIO_USERISPACE || \
(a_uio_t)->uio_segflg == UIO_PHYS_USERSPACE )
#if 1 // UIO_KPI - WARNING OBSOLETE!!!! LP64todo - remove these!!!!
#define IS_UIO_USER_SPACE32( segflg ) \
( (segflg) == UIO_USERSPACE32 || (segflg) == UIO_PHYS_USERSPACE32 || \
(segflg) == UIO_USERISPACE32 )
#define IS_UIO_USER_SPACE64( segflg ) \
( (segflg) == UIO_USERSPACE64 || (segflg) == UIO_PHYS_USERSPACE64 || \
(segflg) == UIO_USERISPACE64 )
#define IS_UIO_USER_SPACE( segflg ) \
( IS_UIO_USER_SPACE32((segflg)) || IS_UIO_USER_SPACE64((segflg)) || \
(segflg) == UIO_USERSPACE || (segflg) == UIO_USERISPACE || \
(segflg) == UIO_PHYS_USERSPACE )
#define IS_UIO_SYS_SPACE32( segflg ) \
( (segflg) == UIO_SYSSPACE32 || (segflg) == UIO_PHYS_SYSSPACE32 || \
(segflg) == UIO_SYSSPACE || (segflg) == UIO_PHYS_SYSSPACE )
#define IS_UIO_SYS_SPACE64( segflg ) \
( (segflg) == UIO_SYSSPACE64 || (segflg) == UIO_PHYS_SYSSPACE64 )
#define IS_UIO_SYS_SPACE( segflg ) \
( IS_UIO_SYS_SPACE32((segflg)) || IS_UIO_SYS_SPACE64((segflg)) )
#define IS_OBSOLETE_UIO_SEGFLG(segflg) \
( (segflg) == UIO_USERSPACE || (segflg) == UIO_USERISPACE || \
(segflg) == UIO_SYSSPACE || (segflg) == UIO_PHYS_USERSPACE || \
(segflg) == UIO_PHYS_SYSSPACE )
#define IS_VALID_UIO_SEGFLG(segflg) \
( IS_UIO_USER_SPACE((segflg)) || IS_UIO_SYS_SPACE((segflg)) )
static inline int64_t uio_uio_resid( struct uio *a_uiop );
static inline void uio_uio_resid_add( struct uio *a_uiop, int64_t a_amount );
static inline void uio_uio_resid_set( struct uio *a_uiop, int64_t a_value );
static inline void uio_iov_base_add( struct uio *a_uiop, int64_t a_amount );
static inline void uio_iov_base_add_at( struct uio *a_uiop, int64_t a_amount, int a_index );
static inline void uio_iov_len_add( struct uio *a_uiop, int64_t a_amount );
static inline void uio_iov_len_add_at( struct uio *a_uiop, int64_t a_amount, int a_index );
static inline u_int64_t uio_iov_len( struct uio *a_uiop );
static inline u_int64_t uio_iov_len_at( struct uio *a_uiop, int a_index );
static inline u_int64_t uio_iov_base( struct uio *a_uiop );
static inline u_int64_t uio_iov_base_at( struct uio *a_uiop, int a_index );
static inline void uio_next_iov( struct uio *a_uiop );
static inline void uio_iov_len_set( struct uio *a_uiop, u_int64_t a_value );
static inline void uio_iov_len_set_at( struct uio *a_uiop, u_int64_t a_value, int a_index );
static inline int64_t uio_uio_resid( struct uio *a_uiop )
{
return( (int64_t)a_uiop->uio_resid );
}
static inline void uio_uio_resid_add( struct uio *a_uiop, int64_t a_amount )
{
a_uiop->uio_resid += ((int32_t) a_amount);
}
static inline void uio_uio_resid_set( struct uio *a_uiop, int64_t a_value )
{
a_uiop->uio_resid = a_value;
}
static inline u_int64_t uio_iov_base( struct uio *a_uiop )
{
return(uio_iov_base_at(a_uiop, 0));
}
static inline u_int64_t uio_iov_base_at( struct uio *a_uiop, int a_index )
{
if (IS_UIO_USER_SPACE32(a_uiop->uio_segflg) || IS_OBSOLETE_UIO_SEGFLG(a_uiop->uio_segflg)) {
return((u_int64_t)((uintptr_t)a_uiop->uio_iovs.iov32p[a_index].iov_base));
}
if (IS_UIO_SYS_SPACE32(a_uiop->uio_segflg)) {
return((u_int64_t)a_uiop->uio_iovs.iov32p[a_index].iov_base);
}
if (IS_UIO_USER_SPACE64(a_uiop->uio_segflg) || IS_UIO_SYS_SPACE64(a_uiop->uio_segflg)) {
return(a_uiop->uio_iovs.iov64p[a_index].iov_base);
}
return(0);
}
static inline u_int64_t uio_iov_len( struct uio *a_uiop )
{
return(uio_iov_len_at(a_uiop, 0));
}
static inline u_int64_t uio_iov_len_at( struct uio *a_uiop, int a_index )
{
if (IS_UIO_USER_SPACE32(a_uiop->uio_segflg) ||
IS_UIO_SYS_SPACE32(a_uiop->uio_segflg) ||
IS_OBSOLETE_UIO_SEGFLG(a_uiop->uio_segflg)) {
return((u_int64_t)a_uiop->uio_iovs.iov32p[a_index].iov_len);
}
if (IS_UIO_USER_SPACE64(a_uiop->uio_segflg) || IS_UIO_SYS_SPACE64(a_uiop->uio_segflg)) {
return(a_uiop->uio_iovs.iov64p[a_index].iov_len);
}
return(0);
}
static inline void uio_iov_len_set_at( struct uio *a_uiop, u_int64_t a_value, int a_index )
{
if (IS_UIO_USER_SPACE32(a_uiop->uio_segflg) ||
IS_UIO_SYS_SPACE32(a_uiop->uio_segflg) ||
IS_OBSOLETE_UIO_SEGFLG(a_uiop->uio_segflg)) {
a_uiop->uio_iovs.iov32p[a_index].iov_len = a_value;
}
else if (IS_UIO_USER_SPACE64(a_uiop->uio_segflg) || IS_UIO_SYS_SPACE64(a_uiop->uio_segflg)) {
a_uiop->uio_iovs.iov64p[a_index].iov_len = a_value;
}
return;
}
static inline void uio_iov_len_set( struct uio *a_uiop, u_int64_t a_value )
{
return(uio_iov_len_set_at(a_uiop, a_value, 0));
}
static inline void uio_iov_len_add_at( struct uio *a_uiop, int64_t a_amount, int a_index )
{
if (IS_UIO_USER_SPACE32(a_uiop->uio_segflg) ||
IS_UIO_SYS_SPACE32(a_uiop->uio_segflg) ||
IS_OBSOLETE_UIO_SEGFLG(a_uiop->uio_segflg)) {
a_uiop->uio_iovs.iov32p[a_index].iov_len += ((int32_t) a_amount);
}
else if (IS_UIO_USER_SPACE64(a_uiop->uio_segflg) || IS_UIO_SYS_SPACE64(a_uiop->uio_segflg)) {
a_uiop->uio_iovs.iov64p[a_index].iov_len += a_amount;
}
return;
}
static inline void uio_iov_len_add( struct uio *a_uiop, int64_t a_amount )
{
return(uio_iov_len_add_at(a_uiop, a_amount, 0));
}
static inline void uio_iov_base_add_at( struct uio *a_uiop, int64_t a_amount, int a_index )
{
if (IS_UIO_USER_SPACE32(a_uiop->uio_segflg) ||
IS_UIO_SYS_SPACE32(a_uiop->uio_segflg) ||
IS_OBSOLETE_UIO_SEGFLG(a_uiop->uio_segflg)) {
a_uiop->uio_iovs.iov32p[a_index].iov_base += ((int32_t) a_amount);
}
else if (IS_UIO_USER_SPACE64(a_uiop->uio_segflg) || IS_UIO_SYS_SPACE64(a_uiop->uio_segflg)) {
a_uiop->uio_iovs.iov64p[a_index].iov_base += a_amount;
}
return;
}
static inline void uio_iov_base_add( struct uio *a_uiop, int64_t a_amount )
{
return(uio_iov_base_add_at(a_uiop, a_amount, 0));
}
static inline void uio_next_iov( struct uio *a_uiop )
{
if (IS_UIO_USER_SPACE32(a_uiop->uio_segflg) ||
IS_UIO_SYS_SPACE32(a_uiop->uio_segflg) ||
IS_OBSOLETE_UIO_SEGFLG(a_uiop->uio_segflg)) {
a_uiop->uio_iovs.iov32p++;
}
else if (IS_UIO_USER_SPACE64(a_uiop->uio_segflg) || IS_UIO_SYS_SPACE64(a_uiop->uio_segflg)) {
a_uiop->uio_iovs.iov64p++;
}
return;
}
static inline void init_iovec( u_int64_t a_base,
u_int64_t a_len,
struct iovec_64 *a_iovp,
int is_64bit_process )
{
if (is_64bit_process) {
a_iovp->iov_base = a_base;
a_iovp->iov_len = a_len;
}
else {
struct iovec_32 *a_iov32p = (struct iovec_32 *) a_iovp;
a_iov32p->iov_base = a_base;
a_iov32p->iov_len = a_len;
}
return;
}
#define INIT_UIO_BASE( uiop, iovcnt, offset, resid, rw, procp ) \
{ \
(uiop)->uio_iovcnt = (iovcnt); \
(uiop)->uio_offset = (offset); \
(uiop)->uio_resid = (resid); \
(uiop)->uio_rw = (rw); \
(uiop)->uio_procp = (procp); \
}
#define INIT_UIO_USER32( uiop, iovp, iovcnt, offset, resid, rw, procp ) \
{ \
(uiop)->uio_iovs.iov32p = (iovp); \
(uiop)->uio_segflg = UIO_USERSPACE; \
INIT_UIO_BASE((uiop), (iovcnt), (offset), (resid), (rw), (procp)); \
}
#define INIT_UIO_USER64( uiop, iovp, iovcnt, offset, resid, rw, procp ) \
{ \
(uiop)->uio_iovs.iov64p = (iovp); \
(uiop)->uio_segflg = UIO_USERSPACE64; \
INIT_UIO_BASE((uiop), (iovcnt), (offset), (resid), (rw), (procp)); \
}
#define INIT_UIO_SYS32( uiop, iovp, iovcnt, offset, resid, rw, procp ) \
{ \
(uiop)->uio_iovs.iov32p = (iovp); \
(uiop)->uio_segflg = UIO_SYSSPACE; \
INIT_UIO_BASE((uiop), (iovcnt), (offset), (resid), (rw), (procp)); \
}
#define INIT_UIO_USERSPACE( uiop, iovp, iovcnt, offset, resid, rw, procp ) \
{ \
if (IS_64BIT_PROCESS((procp))) { \
(uiop)->uio_iovs.iov64p = (iovp); \
(uiop)->uio_segflg = UIO_USERSPACE64; \
} \
else { \
(uiop)->uio_iovs.iov32p = (struct iovec_32 *)(iovp); \
(uiop)->uio_segflg = UIO_USERSPACE; \
} \
INIT_UIO_BASE((uiop), (iovcnt), (offset), (resid), (rw), (procp)); \
}
#define INIT_UIO_SYSSPACE( uiop, iovp, iovcnt, offset, resid, rw, procp ) \
{ \
if (0) { \
(uiop)->uio_iovs.iov64p = (iovp); \
(uiop)->uio_segflg = UIO_SYSSPACE64; \
} \
else { \
(uiop)->uio_iovs.iov32p = (struct iovec_32 *)(iovp); \
(uiop)->uio_segflg = UIO_SYSSPACE; \
} \
INIT_UIO_BASE((uiop), (iovcnt), (offset), (resid), (rw), (procp)); \
}
#endif // UIO_KPI - WARNING OBSOLETE!!!!
#endif
#endif