[BACK]Return to iscsiutil.h CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / dist / iscsi / include

File: [cvs.NetBSD.org] / src / dist / iscsi / include / Attic / iscsiutil.h (download)

Revision 1.1, Mon Nov 12 23:25:40 2007 UTC (16 years, 4 months ago) by agc
Branch: MAIN
CVS Tags: yamt-pf42-baseX, yamt-pf42-base4, yamt-pf42-base3, yamt-pf42-base2, yamt-pf42-base, yamt-pf42, wrstuden-revivesa-base-3, wrstuden-revivesa-base-2, wrstuden-revivesa-base-1, wrstuden-revivesa-base, wrstuden-revivesa, netbsd-5-base, netbsd-5-2-RELEASE, netbsd-5-2-RC1, netbsd-5-2-3-RELEASE, netbsd-5-2-2-RELEASE, netbsd-5-2-1-RELEASE, netbsd-5-2, netbsd-5-1-RELEASE, netbsd-5-1-RC4, netbsd-5-1-RC3, netbsd-5-1-RC2, netbsd-5-1-RC1, netbsd-5-1-5-RELEASE, netbsd-5-1-4-RELEASE, netbsd-5-1-3-RELEASE, netbsd-5-1-2-RELEASE, netbsd-5-1-1-RELEASE, netbsd-5-1, netbsd-5-0-RELEASE, netbsd-5-0-RC4, netbsd-5-0-RC3, netbsd-5-0-RC2, netbsd-5-0-RC1, netbsd-5-0-2-RELEASE, netbsd-5-0-1-RELEASE, netbsd-5-0, netbsd-5, mjf-devfs2-base, mjf-devfs2, matt-nb5-pq3-base, matt-nb5-pq3, matt-nb5-mips64-u2-k2-k4-k7-k8-k9, matt-nb5-mips64-u1-k1-k5, matt-nb5-mips64-premerge-20101231, matt-nb5-mips64-premerge-20091211, matt-nb5-mips64-k15, matt-nb5-mips64, matt-nb4-mips64-k7-u2a-k9b, matt-mips64-base2, matt-armv6-nbase, matt-armv6-base, keiichi-mipv6-base, keiichi-mipv6, jym-xensuspend-nbase, jym-xensuspend-base, jym-xensuspend, hpcarm-cleanup-nbase, hpcarm-cleanup-base, cube-autoconf-base, cube-autoconf
Branch point for: matt-armv6

Rename include/util.h to include/iscsiutil.h to avoid a nameclash
with /usr/include/util.h.

/*
 * IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By downloading, copying, installing or
 * using the software you agree to this license. If you do not agree to this license, do not download, install,
 * copy or use the software.
 *
 * Intel License Agreement
 *
 * Copyright (c) 2000, Intel Corporation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that
 * the following conditions are met:
 *
 * -Redistributions of source code must retain the above copyright notice, this list of conditions and the
 *  following disclaimer.
 *
 * -Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
 *  following disclaimer in the documentation and/or other materials provided with the distribution.
 *
 * -The name of Intel Corporation may not be used to endorse or promote products derived from this software
 *  without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef _ISCSIUTIL_H_
#define _ISCSIUTIL_H_

#include "config.h"

#include <stdio.h>
#include <stdlib.h>

#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif

#ifdef HAVE_STRING_H
#include <string.h>
#endif

#ifdef HAVE_PTHREAD_H
#include <pthread.h>
#endif

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#ifdef HAVE_SYS_UIO_H
#include <sys/uio.h>
#endif

#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif

#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif

#ifdef HAVE_SYSLOG_H
#include <syslog.h>
#endif

/*
 *
 */

#define ISCSI_HTONLL6(x) (uint64_t) \
      ( ((uint64_t)( ((uint64_t)(x) & (uint64_t)0x0000ff0000000000uLL) >> 40))     \
      | ((uint64_t)( ((uint64_t)(x) & (uint64_t)0x000000ff00000000uLL) >> 24))     \
      | ((uint64_t)( ((uint64_t)(x) & (uint64_t)0x00000000ff000000uLL) >> 8))      \
      | ((uint64_t)( ((uint64_t)(x) & (uint64_t)0x0000000000ff0000uLL) << 8))      \
      | ((uint64_t)( ((uint64_t)(x) & (uint64_t)0x000000000000ff00uLL) << 24))     \
      | ((uint64_t)( ((uint64_t)(x) & (uint64_t)0x00000000000000ffuLL) << 40)))

#define ISCSI_NTOHLL6(x) (uint64_t) \
      ( ((uint64_t)( ((uint64_t)(x) & (uint64_t)0x0000ff0000000000uLL) >> 40))     \
      | ((uint64_t)( ((uint64_t)(x) & (uint64_t)0x000000ff00000000uLL) >> 24))     \
      | ((uint64_t)( ((uint64_t)(x) & (uint64_t)0x00000000ff000000uLL) >> 8))      \
      | ((uint64_t)( ((uint64_t)(x) & (uint64_t)0x0000000000ff0000uLL) << 8))      \
      | ((uint64_t)( ((uint64_t)(x) & (uint64_t)0x000000000000ff00uLL) << 24))     \
      | ((uint64_t)( ((uint64_t)(x) & (uint64_t)0x00000000000000ffuLL) << 40)))

/*
 * Debugging Levels
 */

#define TRACE_NET_DEBUG      0x00000001
#define TRACE_NET_BUFF       0x00000002
#define TRACE_NET_IOV        0x00000004
#define TRACE_NET_ALL        (TRACE_NET_DEBUG|TRACE_NET_BUFF|TRACE_NET_IOV)

#define TRACE_ISCSI_DEBUG    0x00000010
#define TRACE_ISCSI_CMD      0x00000020
#define TRACE_ISCSI_ARGS     0x00000040
#define TRACE_ISCSI_PARAM    0x00000080
#define TRACE_ISCSI_ALL      (TRACE_ISCSI_DEBUG|TRACE_ISCSI_ARGS|TRACE_ISCSI_PARAM|TRACE_ISCSI_CMD)

#define TRACE_SCSI_DEBUG     0x00000100
#define TRACE_SCSI_CMD       0x00000200
#define TRACE_SCSI_DATA      0x00000400
#define TRACE_SCSI_ARGS      0x00000800
#define TRACE_SCSI_ALL       (TRACE_SCSI_DEBUG|TRACE_SCSI_CMD|TRACE_SCSI_DATA|TRACE_SCSI_ARGS)

#define TRACE_DEBUG          0x00001000
#define TRACE_HASH           0x00002000
#define TRACE_SYNC           0x00004000
#define TRACE_QUEUE          0x00008000
#define TRACE_WARN           0x00010000
#define TRACE_MEM            0x00020000

#define TRACE_OSD            0x00040000
#define TRACE_OSDFS          0x00080000
#define TRACE_OSDSO          0x00100000
#define TRACE_ALL            0xffffffff

/*
 * Set debugging level here. Turn on debugging in Makefile.
  */
#ifndef EXTERN
#define EXTERN  extern
#endif

EXTERN uint32_t iscsi_debug_level;

/*
 * Debugging Functions
 */
void	set_debug(const char *);
void	iscsi_trace(const int, const char *, const int, const char *, ...);
void	iscsi_trace_warning(const char *, const int, const char *, ...);
void	iscsi_trace_error(const char *, const int, const char *, ...);
void	iscsi_print_buffer(const char *, const size_t);


/*
 * Byte Order
  */

#ifdef HAVE_ASM_BYTEORDER_H
#include <asm/byteorder.h>
#endif

#ifdef HAVE_SYS_BYTEORDER_H
#include <sys/byteorder.h>
#endif

#ifdef HAVE_BYTESWAP_H
#include <byteswap.h>
#endif

#ifdef HAVE_MACHINE_ENDIAN_H
#include <machine/endian.h>
#endif

#define __BYTE_ORDER    _BYTE_ORDER
#define __BIG_ENDIAN    _BIG_ENDIAN
#define __LITTLE_ENDIAN _LITTLE_ENDIAN

#define ISCSI_NTOHLL(a)	ISCSI_BE64TOH(a)
#define ISCSI_HTONLL(a)	ISCSI_HTOBE64(a)
#define ISCSI_NTOHL(a)	ntohl(a)
#define ISCSI_HTONL(a)	htonl(a)
#define ISCSI_NTOHS(a)	ntohs(a)
#define ISCSI_HTONS(a)	htons(a)

#define ISCSI_GETPID getpid()

#ifndef HAVE_SOCKLEN_T
typedef int	socklen_t;
#endif

/*
 * Sleeping
 */

#define ISCSI_SLEEP(N) sleep(N)

/*
 * Memory
 */

void           *iscsi_malloc(unsigned);
void            iscsi_free(void *);
void           *iscsi_malloc_atomic(unsigned);
void            iscsi_free_atomic(void *);

/*
 * Comparison
 */

#ifndef MIN
#define MIN(A,B) (((A)<(B))?(A):(B))
#endif

#define MIN_3(A,B,C) (((A)<(B))?(((A)<(C))?(A):(C)):(((B)<(C))?(B):(C)))

/* Spin locks */

typedef         pthread_mutex_t iscsi_spin_t;

int             iscsi_spin_init(iscsi_spin_t * );
int             iscsi_spin_lock(iscsi_spin_t * );
int             iscsi_spin_unlock(iscsi_spin_t * );
int             iscsi_spin_lock_irqsave(iscsi_spin_t * , uint32_t *);
int             iscsi_spin_unlock_irqrestore(iscsi_spin_t * , uint32_t *);
int             iscsi_spin_destroy(iscsi_spin_t * );

/*
 * End of ISCSI spin routines
 */

/*
 * Tags
 */

#define ISCSI_SET_TAG(tag) do {						\
	iscsi_spin_lock(&g_tag_spin);					\
	*tag = g_tag++;							\
	iscsi_spin_unlock(&g_tag_spin);					\
} while (/* CONSTCOND */ 0)

#define ISCSI_SET_TAG_IN_INTR(tag) do {					\
	uint32_t flags;							\
	iscsi_spin_lock_irqsave(&g_tag_spin, &flags);			\
	*tag = g_tag++;							\
	iscsi_spin_unlock_irqrestore(&g_tag_spin, &flags);		\
} while (/* CONSTCOND */ 0)



/*
 * Hashing
 */


typedef struct hash_t {
	struct initiator_cmd_t **bucket;
	int             collisions;
	int             insertions;
	int             n;
	iscsi_spin_t    lock;
}               hash_t;

int             hash_init(hash_t * , int );
int             hash_insert(hash_t * , struct initiator_cmd_t * , uint32_t );
struct initiator_cmd_t *hash_remove(hash_t * , uint32_t );
int             hash_destroy(hash_t * );

/*
 * Queuing
 */

typedef struct iscsi_queue_t {
	int             head;
	int             tail;
	int             count;
	void          **elem;
	int             depth;
	iscsi_spin_t    lock;
}               iscsi_queue_t;

int             iscsi_queue_init(iscsi_queue_t * , int );
void            iscsi_queue_destroy(iscsi_queue_t * );
int             iscsi_queue_insert(iscsi_queue_t * , void *);
void           *iscsi_queue_remove(iscsi_queue_t * );
int             iscsi_queue_depth(iscsi_queue_t * );
int             iscsi_queue_full(iscsi_queue_t * );

/*
 * Socket Abstraction
 */

typedef int     iscsi_socket_t;

/* Turning off Nagle's Algorithm doesn't always seem to work, */
/* so we combine two messages into one when the second's size */
/* is less than or equal to ISCSI_SOCK_HACK_CROSSOVER. */

#define ISCSI_SOCK_HACK_CROSSOVER    1024
#define ISCSI_SOCK_CONNECT_NONBLOCK  0
#define ISCSI_SOCK_CONNECT_TIMEOUT   1
#define ISCSI_SOCK_MSG_BYTE_ALIGN    4

int             iscsi_sock_create(iscsi_socket_t * );
int             iscsi_socks_establish(iscsi_socket_t *, int *, int *, int, int);
int		iscsi_waitfor_connection(iscsi_socket_t *, int, const char *cf, iscsi_socket_t *);
const char	*iscsi_address_family(int);
int             iscsi_sock_setsockopt(iscsi_socket_t * , int , int , void *, unsigned  );
int             iscsi_sock_getsockopt(iscsi_socket_t * , int , int , void *, unsigned *);
int             iscsi_sock_bind(iscsi_socket_t , int );
int             iscsi_sock_listen(iscsi_socket_t );
int             iscsi_sock_connect(iscsi_socket_t , char *, int );
int             iscsi_sock_accept(iscsi_socket_t , iscsi_socket_t * );
int             iscsi_sock_shutdown(iscsi_socket_t , int );
int             iscsi_sock_close(iscsi_socket_t );
int             iscsi_sock_msg(iscsi_socket_t , int , unsigned , void *, int );
int		iscsi_sock_send_header_and_data(iscsi_socket_t ,
				void *, unsigned ,
				const void *, unsigned , int );
int             iscsi_sock_getsockname(iscsi_socket_t , struct sockaddr * , unsigned *);
int             iscsi_sock_getpeername(iscsi_socket_t , struct sockaddr * , unsigned *);
int             modify_iov(struct iovec ** , int *, uint32_t , uint32_t );


void	cdb2lba(uint32_t *, uint16_t *, uint8_t *);
void	lba2cdb(uint8_t *, uint32_t *, uint16_t *);

/*
 * Mutexes
 */

typedef pthread_mutex_t iscsi_mutex_t;

int             iscsi_mutex_init(iscsi_mutex_t * );
int             iscsi_mutex_lock(iscsi_mutex_t * );
int             iscsi_mutex_unlock(iscsi_mutex_t * );
int             iscsi_mutex_destroy(iscsi_mutex_t * );

#define ISCSI_LOCK(M, ELSE)	do {					\
	if (iscsi_mutex_lock(M) != 0) {					\
		iscsi_trace_error(__FILE__, __LINE__, "iscsi_mutex_lock() failed\n");	\
		ELSE;							\
	}								\
} while (/* CONSTCOND */ 0)

#define ISCSI_UNLOCK(M, ELSE)	do {					\
	if (iscsi_mutex_unlock(M) != 0) {				\
		iscsi_trace_error(__FILE__, __LINE__, "iscsi_mutex_unlock() failed\n");	\
		ELSE;							\
	}								\
} while (/* CONSTCOND */ 0)

#define ISCSI_MUTEX_INIT(M, ELSE) do {					\
	if (iscsi_mutex_init(M) != 0) {					\
		iscsi_trace_error(__FILE__, __LINE__, "iscsi_mutex_init() failed\n");	\
		ELSE;							\
	}								\
} while (/* CONSTCOND */ 0)

#define ISCSI_MUTEX_DESTROY(M, ELSE) do {				\
	if (iscsi_mutex_destroy(M) != 0) {				\
		iscsi_trace_error(__FILE__, __LINE__, "iscsi_mutex_destroy() failed\n");	\
		ELSE;							\
	}								\
} while (/* CONSTCOND */ 0)

/*
 * Condition Variable
 */

typedef pthread_cond_t iscsi_cond_t;

int             iscsi_cond_init(iscsi_cond_t * );
int             iscsi_cond_wait(iscsi_cond_t * , iscsi_mutex_t * );
int             iscsi_cond_signal(iscsi_cond_t * );
int             iscsi_cond_destroy(iscsi_cond_t * );

#define ISCSI_COND_INIT(C, ELSE) do {					\
	if (iscsi_cond_init(C) != 0) {					\
		ELSE;							\
	}								\
} while (/* CONSTCOND */ 0)

#define ISCSI_WAIT(C, M, ELSE)	do {					\
	if (iscsi_cond_wait(C, M) != 0) {				\
		ELSE;							\
	}								\
} while (/* CONSTCOND */ 0)

#define ISCSI_SIGNAL(C, ELSE) 	do {					\
	if (iscsi_cond_signal(C) != 0) {				\
		ELSE;							\
	}								\
} while (/* CONSTCOND */ 0)

#define ISCSI_COND_DESTROY(C, ELSE)	do {				\
	if (iscsi_cond_destroy(C) != 0) {				\
		ELSE;							\
	}								\
} while (/* CONSTCOND */ 0)

/*
 * Threading Routines
 */

typedef struct iscsi_thread_t {
	pthread_t       pthread;
}               iscsi_thread_t;

int             iscsi_thread_create(iscsi_thread_t * , void *(*proc) (void *), void *);

#define ISCSI_SET_THREAD(ME)	/* for user pthread id set by pthread_create
				 * in iscsi_thread_create */
#define ISCSI_THREAD_START(NAME)

/*
 * Worker Thread
 */

#define ISCSI_WORKER_STATE_STARTED   1
#define ISCSI_WORKER_STATE_ERROR     2
#define ISCSI_WORKER_STATE_EXITING   4

typedef struct {
	iscsi_thread_t  thread;
	iscsi_mutex_t   work_mutex;
	iscsi_cond_t    work_cond;
	iscsi_mutex_t   exit_mutex;
	iscsi_cond_t    exit_cond;
	int             id;
	int             pid;
	volatile uint32_t state;
}               iscsi_worker_t;

#define ISCSI_WORKER_EXIT(ME) do {					\
	iscsi_trace(TRACE_ISCSI_DEBUG ,__FILE__, __LINE__, "exiting\n");			\
	(ME)->state |= ISCSI_WORKER_STATE_EXITING;			\
	return 0;							\
} while (/* CONSTCOND */ 0)

/*
 * Spin Lock
 */
#define ISCSI_SPIN

/*
 * Pre/Post condition checking
 */

#define NO_CLEANUP {}
#define RETURN_GREATER(NAME, V1, V2, CU, RC)                         \
if ((V1)>(V2)) {                                                     \
  iscsi_trace_error(__FILE__, __LINE__, "Bad \"%s\": %u > %u.\n", NAME, (unsigned)V1, (unsigned)V2); \
  CU;                                                                \
  return RC;                                                         \
}

#define RETURN_NOT_EQUAL(NAME, V1, V2, CU, RC)                       \
if ((V1)!=(V2)) {                                                    \
  iscsi_trace_error(__FILE__, __LINE__, "Bad \"%s\": Got %u expected %u.\n", NAME, V1, V2);    \
  CU;                                                                \
  return RC;                                                         \
}

#define WARN_NOT_EQUAL(NAME, V1, V2)                                 \
if ((V1)!=(V2)) {                                                    \
  iscsi_trace_warning(__FILE__, __LINE__, "Bad \"%s\": Got %u expected %u.\n", NAME, V1, V2);  \
}

#define RETURN_EQUAL(NAME, V1, V2, CU, RC)                           \
if ((V1)==(V2)) {                                                    \
  iscsi_trace_error(__FILE__, __LINE__, "Bad \"%s\": %u == %u.\n", NAME, V1, V2);              \
  CU;                                                                \
  return RC;                                                         \
}

/*
 * Misc. Functions
 */

uint32_t        iscsi_atoi(char *);
int HexTextToData(const char *, uint32_t , uint8_t *, uint32_t );
int HexDataToText(uint8_t *, uint32_t , char *, uint32_t );
void            GenRandomData(uint8_t *, uint32_t );

/* this is the maximum number of iovecs which we can use in iscsi_sock_send_header_and_data */
#ifndef ISCSI_MAX_IOVECS
#define ISCSI_MAX_IOVECS        32
#endif

enum {  
	/* used in iscsi_sock_msg() */
	Receive = 0,
	Transmit = 1
};

int		allow_netmask(const char *, const char *);

#endif				/* _ISCSIUTIL_H_ */