[Open-FCoE] [PATCH] libhbalinux: Clarification of the installation procedure document

Steve Ma steve.ma at intel.com
Wed Oct 8 00:42:57 UTC 2008


This patch is to clarify the installation procedure in the INSTALL
document, and also change the source code directory name "libhbalinux"
to "src".

Signed-off-by: Steve Ma <steve.ma at intel.com>
---

 INSTALL                  |   44 ++--
 Makefile                 |    8 -
 libhbalinux/Makefile     |  114 ----------
 libhbalinux/adapt.c      |  417 -----------------------------------
 libhbalinux/adapt_impl.h |  184 ----------------
 libhbalinux/api_lib.h    |   29 --
 libhbalinux/bind.c       |  353 ------------------------------
 libhbalinux/bind_impl.h  |   31 ---
 libhbalinux/lib.c        |  167 --------------
 libhbalinux/lport.c      |  545 ----------------------------------------------
 libhbalinux/pci.c        |  230 -------------------
 libhbalinux/rport.c      |  207 -----------------
 libhbalinux/scsi.c       |  203 -----------------
 libhbalinux/sg.c         |  262 ----------------------
 libhbalinux/utils.c      |  347 -----------------------------
 libhbalinux/utils.h      |  176 ---------------
 src/Makefile             |  114 ++++++++++
 src/adapt.c              |  417 +++++++++++++++++++++++++++++++++++
 src/adapt_impl.h         |  184 ++++++++++++++++
 src/api_lib.h            |   29 ++
 src/bind.c               |  353 ++++++++++++++++++++++++++++++
 src/bind_impl.h          |   31 +++
 src/lib.c                |  167 ++++++++++++++
 src/lport.c              |  545 ++++++++++++++++++++++++++++++++++++++++++++++
 src/pci.c                |  230 +++++++++++++++++++
 src/rport.c              |  207 +++++++++++++++++
 src/scsi.c               |  203 +++++++++++++++++
 src/sg.c                 |  262 ++++++++++++++++++++++
 src/utils.c              |  347 +++++++++++++++++++++++++++++
 src/utils.h              |  176 +++++++++++++++
 30 files changed, 3291 insertions(+), 3291 deletions(-)
 delete mode 100644 libhbalinux/Makefile
 delete mode 100644 libhbalinux/adapt.c
 delete mode 100644 libhbalinux/adapt_impl.h
 delete mode 100644 libhbalinux/api_lib.h
 delete mode 100644 libhbalinux/bind.c
 delete mode 100644 libhbalinux/bind_impl.h
 delete mode 100644 libhbalinux/lib.c
 delete mode 100644 libhbalinux/lport.c
 delete mode 100644 libhbalinux/pci.c
 delete mode 100644 libhbalinux/rport.c
 delete mode 100644 libhbalinux/scsi.c
 delete mode 100644 libhbalinux/sg.c
 delete mode 100644 libhbalinux/utils.c
 delete mode 100644 libhbalinux/utils.h
 create mode 100644 src/Makefile
 create mode 100644 src/adapt.c
 create mode 100644 src/adapt_impl.h
 create mode 100644 src/api_lib.h
 create mode 100644 src/bind.c
 create mode 100644 src/bind_impl.h
 create mode 100644 src/lib.c
 create mode 100644 src/lport.c
 create mode 100644 src/pci.c
 create mode 100644 src/rport.c
 create mode 100644 src/scsi.c
 create mode 100644 src/sg.c
 create mode 100644 src/utils.c
 create mode 100644 src/utils.h

diff --git a/INSTALL b/INSTALL
index d5440bf..47dcf5a 100644
--- a/INSTALL
+++ b/INSTALL
@@ -2,17 +2,16 @@
                ==========================================
 
 
-Download hbalinux package from www.open-fcoe.org
--------------------------------------------------
+Download libhbalinux package from www.open-fcoe.org
+---------------------------------------------------
 
-Download the package of hbalinux from www.Open-FCoE.org and unpack it.
-The default directory to place this source tree is /usr/local/src. You
-may place it anywhere you like. Initially, the source tree contains
+Download the package of libhbalinux from www.Open-FCoE.org and unpack it.
+You may place it anywhere you like. Initially, the source tree contains
 
-hbalinux/
+libhbalinux/
     include/
         ...
-    libhbalinux/
+    src/
         ...
     patches/
         ...
@@ -25,12 +24,14 @@ hbalinux/
 Download hbaapi_src_2.2.tgz and patch the package
 -------------------------------------------------
 
-Next step is to download the hbaapi_src_2.2.tgz package, unpack it
-and patch it.
+   Download hbaapi_src_2.2.tgz from http://sourceforge.net/projects/hbaapi/ or
+   http://sourceforge.net/project/showfiles.php?group_id=35200&package_id=27501&release_id=143305
+   The links may change, we do not have control to them.
+
+   After the download is done, You may place hbaapi_src_2.2.tgz to anywhere you like.
 
-   Download hbaapi_src_2.2.tgz from http://sourceforge.net/
-   cd hbalinux
-   tar zxf hbaapi_src_2.2.tgz
+   cd libhbalinux
+   tar zxf <your path>/hbaapi_src_2.2.tgz
    cd hbaapi_src_2.2
    patch HBAAPILIB.c < ../patches/hbaapi2.2.patch
 
@@ -38,27 +39,25 @@ and patch it.
 Build and install the libraries
 -------------------------------
 
-1) Build and install the libraries.
+1) Because the HBAAPI vendor library invokes the libpciaccess library.
+   The libpciaccess-devel package must be installed before you can
+   build the vendor library.
+
+2) Build and install the libraries.
 
-   cd hbalinux
+   cd libhbalinux
 
    To build the libraries, issue
 
        make
+       make install
 
    To cleanup the binaries, issue
 
        make clean
-
-   To build and install the libraries, issue
-
-       make install
-
-   To uninstall the libraries, issue
-
        make uninstall
 
-2) After build is completed sucessfully, there are two libraries generated:
+3) After build is completed sucessfully, there are two libraries generated:
    libHBAAPI.so and libhbalinux.so.  The installation process adds the
    following files to the X86_64 system,
 
@@ -76,3 +75,4 @@ Build and install the libraries
    string to indicate the location of the vendor library, i.e. libhbalinux.so,
    this allows libHBAAPI.so to load libhbalinux.so at initialization time.
 
+
diff --git a/Makefile b/Makefile
index b6f480f..9c8c46d 100644
--- a/Makefile
+++ b/Makefile
@@ -8,17 +8,17 @@ HBAAPI=$(shell (cd hbaapi_src_2.2; pwd))
 
 all:
 	(cd $(HBAAPI); $(MAKE) -f ../Makefile.hbaapi)
-	$(MAKE) HBAAPI=$(HBAAPI) -C libhbalinux
+	$(MAKE) HBAAPI=$(HBAAPI) -C src
 
 install:
 	(cd $(HBAAPI); $(MAKE) -f ../Makefile.hbaapi install)
-	$(MAKE) HBAAPI=$(HBAAPI) -C libhbalinux install
+	$(MAKE) HBAAPI=$(HBAAPI) -C src install
 
 uninstall:
 	(cd $(HBAAPI); $(MAKE) -f ../Makefile.hbaapi uninstall)
-	$(MAKE) -C libhbalinux uninstall
+	$(MAKE) -C src uninstall
 
 clean:
 	@(cd $(HBAAPI); $(MAKE) -f ../Makefile.hbaapi clean > /dev/null 2>&1)
-	@$(MAKE) -C libhbalinux clean > /dev/null 2>&1
+	@$(MAKE) -C src clean > /dev/null 2>&1
 
diff --git a/libhbalinux/Makefile b/libhbalinux/Makefile
deleted file mode 100644
index 819881c..0000000
--- a/libhbalinux/Makefile
+++ /dev/null
@@ -1,114 +0,0 @@
-#
-# Makefile for libhbalinux
-#
-
-#
-# The target shared library to be built
-#
-LIB = libhbalinux.so
-
-#
-# List of legal build component names
-#
-LEGAL_ARCH = i386 i486 i586 i686 x86_64
-LEGAL_OS = linux Linux
-
-#
-# Default build directory
-#
-BUILD_DIR := .
-
-#
-# Commands used for build
-#
-CC = cc 
-RM = rm
-SED = sed
-INSTALL = install
-
-#
-#
-# Validating OS and the machine architecture.
-#
-ifneq "$(filter-out $(LEGAL_ARCH), $(shell uname -i))" ""
-    $(error bad build architecture $(shell uname -i))
-else
-ifneq "$(filter-out $(LEGAL_OS), $(shell uname -s))" ""
-    $(error bad build OS $(shell uname -s))
-else
-
-ifeq ($(shell uname -i),x86_64)
-    CFLAGS += -m64
-    .LIBPATTERNS = /usr/lib64/lib%.so /usr/lib64/lib%.a
-    INSTALL_DIR := /usr/local/lib64
-else
-    .LIBPATTERNS = /usr/lib/lib%.so \
-                   /usr/lib/lib%.a \
-                   /usr/local/lib/lib%.a \
-                   /usr/local/lib/lib%.so
-    INSTALL_DIR := /usr/local/lib
-endif
-
-LIBRARIES = -lrt -lpciaccess
-
-#
-# Set up the C compiler flags
-#
-#DATE=`date "+%D-%T"`
-DATE=`date "+%Y/%m/%d %T %Z"`
-CFLAGS += -DBUILD_DATE="\"${DATE}\""
-CFLAGS += -fPIC -O0 -g -Wall -Wall -Werror
-CFLAGS += -I.
-CFLAGS += -I../include
-CFLAGS += -I../hbaapi_src_2.2
-
-#
-# C files to be compiled
-#
-SOURCES += \
-	lib.c \
-	adapt.c \
-	lport.c \
-	rport.c \
-	bind.c \
-	pci.c \
-	scsi.c \
-	sg.c \
-	utils.c \
-	$(NULL)
-
-#
-# The make rules
-#
-
-all: $(LIB)
-
-LIB_SO := $(filter %.so, $(LIB))
-PICS := $(basename $(SOURCES))
-PICS := $(PICS:%=$(BUILD_DIR)/%.o)
-
-$(LIB_SO): $(PICS)
-	@echo '       LINK' $@; \
-	$(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $^ $(LIBRARIES)
-
-$(BUILD_DIR)/%.o: %.c
-	@echo '       CC PIC' $<; \
-	$(CC) -MM $(CFLAGS) -fpic $< | \
-		( $(SED) 's,$*\.o[ :]*,$@: ,g' > $(BUILD_DIR)/$*.d || \
-		$(RM) -f $(BUILD_DIR)/$*.d ); \
-	$(CC) -c $(CFLAGS) -fpic -o $@ $<
-
-clean:
-	@$(RM) -f *.o *.d $(LIB) > /dev/null 2>&1
-
-install: libhbalinux.so
-	@echo '       INSTALL' $<
-	@$(INSTALL) libhbalinux.so $(INSTALL_DIR)
-
-uninstall:
-	@$(RM) -f $(INSTALL_DIR)/libhbalinux.so > /dev/null 2>&1
-
--include $(PICS:%.o=%.d)
-
-endif
-endif
diff --git a/libhbalinux/adapt.c b/libhbalinux/adapt.c
deleted file mode 100644
index cdeba76..0000000
--- a/libhbalinux/adapt.c
+++ /dev/null
@@ -1,417 +0,0 @@
-/*
- * Copyright (c) 2008, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU Lesser General Public License,
- * version 2.1, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include "utils.h"
-#include "api_lib.h"
-#include "adapt_impl.h"
-
-static struct sa_table adapter_table;
-static const u_int32_t adapter_handle_offset = 0x100;
-
-#define HBA_SHORT_NAME_LIMIT    64
-
-/*
- * Support for adapter information.
- */
-HBA_UINT32
-adapter_get_count(void)
-{
-	return adapter_table.st_limit;
-}
-
-/*
- * Get adapter name.
- */
-HBA_STATUS
-adapter_get_name(HBA_UINT32 index, char *buf)
-{
-	HBA_STATUS status;
-	struct adapter_info *ap;
-
-	status = HBA_STATUS_ERROR_ILLEGAL_INDEX;
-	ap = sa_table_lookup(&adapter_table, index);
-	if (ap != NULL) {
-		snprintf(buf, HBA_SHORT_NAME_LIMIT,
-			"%s-%u", ap->ad_name, index);
-		status = HBA_STATUS_OK;
-	}
-	return status;
-}
-
-/*
- * Add an adapter to the table.
- */
-HBA_STATUS
-adapter_create(struct adapter_info *ap)
-{
-	int index;
-
-	index = sa_table_append(&adapter_table, ap);
-	if (index < 0)
-		return HBA_STATUS_ERROR;
-	ap->ad_index = index;
-	return HBA_STATUS_OK;
-}
-
-void
-adapter_destroy(struct adapter_info *ap)
-{
-	sa_table_destroy_all(&ap->ad_ports);
-	free(ap);
-}
-
-void
-adapter_destroy_all(void)
-{
-	struct adapter_info *ap;
-	int i;
-
-	for (i = 0; i < adapter_table.st_limit; i++) {
-		ap = adapter_table.st_table[i];
-		if (ap) {
-			adapter_table.st_table[i] = NULL;
-			adapter_destroy(ap);
-		}
-	}
-	sa_table_destroy(&adapter_table);
-}
-
-struct adapter_info *
-adapter_open_handle(HBA_HANDLE handle)
-{
-	return sa_table_lookup(&adapter_table, handle -
-			       adapter_handle_offset);
-}
-
-struct port_info *
-adapter_get_port(HBA_HANDLE handle, HBA_UINT32 port)
-{
-	struct adapter_info *ap;
-	struct port_info *pp = NULL;
-
-	ap = adapter_open_handle(handle);
-	if (ap)
-		pp = sa_table_lookup(&ap->ad_ports, port);
-	return pp;
-}
-
-struct port_info *
-adapter_get_rport(HBA_HANDLE handle, HBA_UINT32 port, HBA_UINT32 rport)
-{
-	struct port_info *pp;
-	struct port_info *rp = NULL;
-
-	pp = adapter_get_port(handle, port);
-	if (pp) {
-		get_rport_info(pp);
-		rp = sa_table_lookup(&pp->ap_rports, rport);
-	}
-	return rp;
-}
-
-/*
- * Get the Nth discovered port information.
- */
-struct port_info *
-adapter_get_rport_n(HBA_HANDLE handle, HBA_UINT32 port, HBA_UINT32 n)
-{
-	struct port_info *pp;
-	struct port_info *rp = NULL;
-
-	pp = adapter_get_port(handle, port);
-	if (pp) {
-		get_rport_info(pp);
-		rp = sa_table_lookup_n(&pp->ap_rports, n);
-	}
-	return rp;
-}
-
-static void *
-adapter_target_match(void *rp_arg, void *target_arg)
-{
-	struct port_info *rp = rp_arg;
-
-	if (rp->ap_scsi_target != *(u_int32_t *)target_arg)
-		rp_arg = NULL;
-	return rp_arg;
-}
-
-/*
- * Get the rport by scsi_target number.
- */
-struct port_info *
-adapter_get_rport_target(HBA_HANDLE handle, HBA_UINT32 port, HBA_UINT32 n)
-{
-	struct port_info *pp;
-	struct port_info *rp = NULL;
-
-	pp = adapter_get_port(handle, port);
-	if (pp) {
-		get_rport_info(pp);
-		rp = sa_table_search(&pp->ap_rports,
-				     adapter_target_match, &n);
-	}
-	return rp;
-}
-
-static void *
-adapter_wwpn_match(void *rp_arg, void *wwpn_arg)
-{
-	struct port_info *rp = rp_arg;
-
-	if (memcmp(&rp->ap_attr.PortWWN, wwpn_arg, sizeof(HBA_WWN)) != 0)
-		rp_arg = NULL;
-	return rp_arg;
-}
-
-struct port_info *
-adapter_get_rport_by_wwn(struct port_info *pp, HBA_WWN wwpn)
-{
-	struct port_info *rp;
-
-	get_rport_info(pp);
-	rp = sa_table_search(&pp->ap_rports, adapter_wwpn_match, &wwpn);
-	return rp;
-}
-
-static void *
-adapter_fcid_match(void *rp_arg, void *fcid_arg)
-{
-	struct port_info *rp = rp_arg;
-
-	if (rp->ap_attr.PortFcId != *(fc_fid_t *)fcid_arg)
-		rp_arg = NULL;
-	return rp_arg;
-}
-
-struct port_info *
-adapter_get_rport_by_fcid(struct port_info *pp, fc_fid_t fcid)
-{
-	struct port_info *rp;
-
-	get_rport_info(pp);
-	rp = sa_table_search(&pp->ap_rports, adapter_fcid_match, &fcid);
-	return rp;
-}
-
-/*
- * Open adapter by name.
- */
-HBA_HANDLE
-adapter_open(char *name)
-{
-	char buf[256];
-	HBA_HANDLE i;
-	HBA_STATUS status;
-
-	for (i = 0; i < adapter_table.st_limit; i++) {
-		status = adapter_get_name(i, buf);
-		if (status != HBA_STATUS_OK)
-			return 0;
-		if (!strcmp(buf, name))
-			return adapter_handle_offset + i;
-	}
-	return 0;
-}
-
-/*
- * Get port by WWPN.
- * Returns NULL if WWN not unique.
- * If countp is non-NULL, the int it points to will be set to the
- * number found so that the caller can tell if the WWN was ambiguous.
- */
-struct port_info *
-adapter_get_port_by_wwn(HBA_HANDLE handle, HBA_WWN wwn, int *countp)
-{
-	struct adapter_info *ap;
-	struct port_info *pp_found = NULL;
-	struct port_info *pp;
-	int count = 0;
-	int p;
-
-	ap = adapter_open_handle(handle);
-	if (ap != NULL) {
-		for (p = 0; p < ap->ad_ports.st_limit; p++) {
-			pp = ap->ad_ports.st_table[p];
-			if (pp &&
-			    !memcmp(&pp->ap_attr.PortWWN, &wwn, sizeof(wwn))) {
-				count++;
-				pp_found = pp;
-			}
-		}
-	}
-	if (count > 1)
-		pp_found = NULL;
-	if (countp != NULL)
-		*countp = count;
-	return pp_found;
-}
-
-/*
- * Open adapter by WWN.
- */
-HBA_STATUS
-adapter_open_by_wwn(HBA_HANDLE *phandle, HBA_WWN wwn)
-{
-	struct adapter_info *ap;
-	struct port_info *pp;
-	HBA_HANDLE found_handle = 0;
-	int count = 0;
-	HBA_STATUS status;
-	int i;
-	int p;
-
-	for (i = 0; i < adapter_table.st_limit; i++) {
-		ap = adapter_table.st_table[i];
-		if (!ap)
-			continue;
-		if (memcmp(&ap->ad_attr.NodeWWN, &wwn, sizeof(wwn)) == 0) {
-			count++;
-			found_handle = ap->ad_index + adapter_handle_offset;
-		} else {
-			for (p = 0; p < ap->ad_ports.st_limit; p++) {
-				pp = ap->ad_ports.st_table[p];
-				if (!pp)
-					continue;
-				if (memcmp(&pp->ap_attr.PortWWN,
-					   &wwn, sizeof(wwn)) == 0) {
-					count++;
-					found_handle = ap->ad_index +
-						       adapter_handle_offset;
-				}
-			}
-		}
-	}
-
-	*phandle = HBA_HANDLE_INVALID;
-	if (count == 1) {
-		status = HBA_STATUS_OK;
-		*phandle = found_handle;
-	} else if (count > 1) {
-		status = HBA_STATUS_ERROR_AMBIGUOUS_WWN;
-	} else {
-		status = HBA_STATUS_ERROR_ILLEGAL_WWN;
-	}
-	return status;
-}
-
-/*
- * Close adapter.
- */
-void
-adapter_close(HBA_HANDLE handle)
-{
-}
-
-/*
- * Get adapter attributes.
- */
-HBA_STATUS
-adapter_get_attr(HBA_HANDLE handle, HBA_ADAPTERATTRIBUTES *pattr)
-{
-	struct adapter_info *ap;
-
-	ap = adapter_open_handle(handle);
-	if (ap) {
-		*pattr = ap->ad_attr;       /* struct copy */
-		return HBA_STATUS_OK;
-	}
-	return HBA_STATUS_ERROR;
-}
-
-/*
- * Get adapter port attributes.
- */
-HBA_STATUS
-adapter_get_port_attr(HBA_HANDLE handle, HBA_UINT32 port,
-			HBA_PORTATTRIBUTES *pattr)
-{
-	struct port_info *pp;
-
-	pp = adapter_get_port(handle, port);
-	if (pp) {
-		*pattr = pp->ap_attr;       /* struct copy */
-		return HBA_STATUS_OK;
-	}
-	return HBA_STATUS_ERROR;
-}
-
-/*
- * Get discovered (remote) port attributes.
- */
-HBA_STATUS
-adapter_get_rport_attr(HBA_HANDLE handle, HBA_UINT32 port, HBA_UINT32 rport,
-			 HBA_PORTATTRIBUTES *pattr)
-{
-	struct port_info *rp;
-
-	rp = adapter_get_rport_n(handle, port, rport);
-	if (rp) {
-		*pattr = rp->ap_attr;       /* struct copy */
-		return HBA_STATUS_OK;
-	}
-	return HBA_STATUS_ERROR;
-}
-
-/*
- * Get adapter port attributes.
- */
-HBA_STATUS
-adapter_get_port_attr_by_wwn(HBA_HANDLE handle, HBA_WWN wwn,
-			       HBA_PORTATTRIBUTES *pattr)
-{
-	struct adapter_info *ap;
-	struct port_info *pp;
-	struct port_info *pp_found = NULL;
-	u_int32_t p;
-	int count = 0;
-	HBA_STATUS status;
-
-	ap = adapter_open_handle(handle);
-	if (ap != NULL) {
-		for (p = 0; p < ap->ad_ports.st_limit; p++) {
-			pp = ap->ad_ports.st_table[p];
-			if (pp == NULL)
-				continue;
-			if (!memcmp(&pp->ap_attr.PortWWN, &wwn, sizeof(wwn))) {
-				count++;
-				pp_found = pp;
-			}
-			pp = sa_table_search(&pp->ap_rports,
-					     adapter_wwpn_match,
-					     &wwn);
-			if (pp) {
-				count++;
-				pp_found = pp;
-			}
-		}
-	}
-	pp = pp_found;
-	if (pp != NULL) {
-		if (count > 1) {
-			status = HBA_STATUS_ERROR_AMBIGUOUS_WWN;
-		} else {
-			*pattr = pp->ap_attr;       /* struct copy */
-			status = HBA_STATUS_OK;
-		}
-	} else {
-		status = HBA_STATUS_ERROR_ILLEGAL_WWN;
-	}
-	return status;
-}
-
diff --git a/libhbalinux/adapt_impl.h b/libhbalinux/adapt_impl.h
deleted file mode 100644
index b0646b6..0000000
--- a/libhbalinux/adapt_impl.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (c) 2008, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU Lesser General Public License,
- * version 2.1, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#ifndef _ADAPT_IMPL_H_
-#define _ADAPT_IMPL_H_
-
-#define SYSFS_HOST_DIR     "/sys/class/fc_host"
-#define SYSFS_HBA_DIR      "/sys/class/net"
-#define SYSFS_LUN_DIR      "/sys/class/scsi_device"
-#define SYSFS_MODULE       "/driver/module"
-#define SYSFS_MODULE_VER   "driver/module/version"
-#define SYSFS_RPORT_ROOT       "/sys/class/fc_remote_ports"
-#define SYSFS_RPORT_DIR        "rport-%u:%u-%u" /* host, chan, rport */
-
-struct hba_info {
-	u_int32_t	domain;
-	u_int32_t	bus;
-	u_int32_t	dev;
-	u_int32_t	func;
-	u_int32_t	vendor_id;
-	u_int32_t	subsystem_vendor_id;
-	u_int32_t	subsystem_device_id;
-	u_int32_t	device_id;
-	u_int32_t	device_class;
-	u_int32_t	irq;
-	char		Manufacturer[64];
-	char		SerialNumber[64];
-	char		Model[256];
-	char		ModelDescription[256];
-	char		HardwareVersion[256];
-	char		OptionROMVersion[256];
-	char		FirmwareVersion[256];
-	u_int32_t	VendorSpecificID;
-	u_int32_t	NumberOfPorts;
-};
-
-#define MAX_DRIVER_NAME_LEN	20
-#define ARRAY_SIZE(a)		(sizeof(a)/sizeof((a)[0]))
-
-/* fc_port_type: copied from scsi_transport_fc.h */
-enum fc_port_type {
-	FC_PORTTYPE_UNKNOWN,
-	FC_PORTTYPE_OTHER,
-	FC_PORTTYPE_NOTPRESENT,
-	FC_PORTTYPE_NPORT,		/* Attached to FPort */
-	FC_PORTTYPE_NLPORT,		/* (Public) Loop w/ FLPort */
-	FC_PORTTYPE_LPORT,		/* (Private) Loop w/o FLPort */
-	FC_PORTTYPE_PTP,		/* Point to Point w/ another NPort */
-	FC_PORTTYPE_NPIV,		/* VPORT based on NPIV */
-};
-
-#define fc_enum_name_search(title, table_type, table) \
-static const enum fc_port_type get_fc_##title##_value(const char *table_key) \
-{ \
-	int i; enum fc_port_type value = 0; \
-	for (i = 0; i < ARRAY_SIZE(table); i++) { \
-		if (!strcmp(table[i].name, table_key)) { \
-			value = table[i].value; \
-			break; \
-		} \
-	} \
-	return value; \
-}
-
-HBA_STATUS sysfs_get_port_stats(char *dir, HBA_PORTSTATISTICS *sp);
-HBA_STATUS sysfs_get_port_fc4stats(char *dir, HBA_FC4STATISTICS *fc4sp);
-
-extern struct sa_nameval port_states_table[];
-extern struct sa_nameval port_speeds_table[];
-extern void adapter_scan(void);
-extern int sys_read_wwn(const char *, const char *, HBA_WWN *);
-extern HBA_STATUS find_pci_device(struct hba_info *);
-
-/*
- * per-adapter interface.
- */
-
-/*
- * Information about a particular adapter.
- */
-struct adapter_info {
-    u_int32_t               ad_index;       /* adapter's library index */
-    u_int32_t               ad_kern_index;  /* adapter's kernel index */
-    const char              *ad_name;       /* adapter driver name */
-    struct sa_table         ad_ports;       /* table of ports */
-    u_int32_t               ad_port_count;  /* adapter's number of ports */
-    HBA_ADAPTERATTRIBUTES   ad_attr;        /* HBA-API attributes */
-};
-
-/*
- * Information about a port on an adapter or a discovered remote port.
- */
-struct port_info {
-    struct adapter_info     *ap_adapt;
-    u_int32_t               ap_index;
-    u_int32_t               ap_disc_index;  /* discovered port index */
-    u_int32_t               ap_scsi_target; /* SCSI target index (rports) */
-    u_int32_t               ap_kern_hba;    /* kernel HBA index (rports) */
-    struct sa_table         ap_rports;      /* discovered ports */
-    HBA_PORTATTRIBUTES      ap_attr;        /* HBA-API port attributes */
-    char                    host_dir[80];   /* sysfs directory save area */
-};
-
-/*
- * Internal functions.
- */
-HBA_UINT32 adapter_get_count(void);
-HBA_STATUS adapter_get_name(HBA_UINT32 index, char *);
-struct port_info *adapter_get_port_by_wwn(HBA_HANDLE, HBA_WWN, int *countp);
-HBA_STATUS adapter_create(struct adapter_info *);
-void adapter_destroy(struct adapter_info *);
-void adapter_destroy_all(void);
-struct adapter_info *adapter_open_handle(HBA_HANDLE);
-struct port_info *adapter_get_port(HBA_HANDLE, HBA_UINT32 port);
-struct port_info *adapter_get_rport(HBA_HANDLE, HBA_UINT32, HBA_UINT32);
-struct port_info *adapter_get_rport_n(HBA_HANDLE, HBA_UINT32, HBA_UINT32);
-struct port_info *adapter_get_rport_target(HBA_HANDLE, HBA_UINT32, HBA_UINT32);
-struct port_info *adapter_get_rport_by_wwn(struct port_info *, HBA_WWN);
-struct port_info *adapter_get_rport_by_fcid(struct port_info *, fc_fid_t);
-void get_rport_info(struct port_info *);
-void sg_get_dev_id(const char *name, char *buf, size_t result_len);
-void copy_wwn(HBA_WWN *dest, fc_wwn_t src);
-int is_wwn_nonzero(HBA_WWN *wwn);
-HBA_STATUS sg_issue_read_capacity(const char *, void *, HBA_UINT32 *,
-			HBA_UINT8 *, void *, HBA_UINT32 *);
-HBA_STATUS sg_issue_report_luns(const char *, void *, HBA_UINT32 *,
-			HBA_UINT8 *, void *, HBA_UINT32 *);
-
-/*
- * Library functions.
- */
-HBA_HANDLE adapter_open(char *name);
-HBA_STATUS adapter_open_by_wwn(HBA_HANDLE *, HBA_WWN);
-void adapter_close(HBA_HANDLE);
-HBA_STATUS adapter_get_attr(HBA_HANDLE, HBA_ADAPTERATTRIBUTES *);
-HBA_STATUS adapter_get_port_attr(HBA_HANDLE, HBA_UINT32 port,
-				HBA_PORTATTRIBUTES *);
-HBA_STATUS adapter_get_port_attr_by_wwn(HBA_HANDLE, HBA_WWN,
-				HBA_PORTATTRIBUTES *);
-HBA_STATUS adapter_get_rport_attr(HBA_HANDLE, HBA_UINT32 port,
-				HBA_UINT32 rport, HBA_PORTATTRIBUTES *);
-HBA_STATUS get_port_statistics(HBA_HANDLE, HBA_UINT32 port,
-				HBA_PORTSTATISTICS *);
-HBA_STATUS get_port_fc4_statistics(HBA_HANDLE, HBA_WWN,
-				HBA_UINT8 fc4_type, HBA_FC4STATISTICS *);
-HBA_STATUS scsi_read_capacity_v1(HBA_HANDLE, HBA_WWN, HBA_UINT64,
-				void *, HBA_UINT32, void *, HBA_UINT32);
-HBA_STATUS scsi_read_capacity_v2(HBA_HANDLE, HBA_WWN, HBA_WWN,
-			HBA_UINT64, void *, HBA_UINT32 *, HBA_UINT8 *,
-			void *, HBA_UINT32 *);
-HBA_STATUS scsi_inquiry_v1(HBA_HANDLE, HBA_WWN, HBA_UINT64, HBA_UINT8,
-			HBA_UINT32, void *, HBA_UINT32, void *, HBA_UINT32);
-HBA_STATUS scsi_inquiry_v2(HBA_HANDLE, HBA_WWN, HBA_WWN, HBA_UINT64,
-			HBA_UINT8, HBA_UINT8, void *, HBA_UINT32 *,
-			HBA_UINT8 *, void *, HBA_UINT32 *);
-HBA_STATUS scsi_report_luns_v1(HBA_HANDLE, HBA_WWN,
-			void *, HBA_UINT32, void *, HBA_UINT32);
-HBA_STATUS scsi_report_luns_v2(HBA_HANDLE, HBA_WWN, HBA_WWN,
-			void *, HBA_UINT32 *, HBA_UINT8 *,
-			void *, HBA_UINT32 *);
-HBA_STATUS sg_issue_inquiry(const char *, HBA_UINT8, HBA_UINT8,
-		void *, HBA_UINT32 *, HBA_UINT8 *, void *, HBA_UINT32 *);
-
-void adapter_init(void);
-void adapter_shutdown(void);
-
-/* struct port_stats; */
-
-#endif /* _ADAPT_IMPL_H_ */
diff --git a/libhbalinux/api_lib.h b/libhbalinux/api_lib.h
deleted file mode 100644
index d625a79..0000000
--- a/libhbalinux/api_lib.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2008, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU Lesser General Public License,
- * version 2.1, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#ifndef _API_LIB_H_
-#define _API_LIB_H_
-
-/*
- * Definitions used by the OpenFC-specific library for the SNIA HBA-API.
- */
-#define	HBA_API_VENDOR        "Open-FC.org"
-#define	HBA_API_VERSION       "2.2"
-#define	HBA_API_VENDOR_RURL   "org.open-fc"	/* reversed URL */
-
-#endif /* _API_LIB_H_ */
diff --git a/libhbalinux/bind.c b/libhbalinux/bind.c
deleted file mode 100644
index eaf8549..0000000
--- a/libhbalinux/bind.c
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * Copyright (c) 2008, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU Lesser General Public License,
- * version 2.1, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include "utils.h"
-#include "api_lib.h"
-#include "adapt_impl.h"
-#include "bind_impl.h"
-
-/*
- * Binding capabilities we understand.
- */
-#define BINDING_CAPABILITIES   (HBA_CAN_BIND_TO_D_ID | \
-				HBA_CAN_BIND_TO_WWPN | \
-				HBA_CAN_BIND_TO_WWNN)
-#define SYSFS_BIND		"tgtid_bind_type"
-
-/*
- * Name-value strings for kernel bindings.
- * The first word of the strings must exactly match those in
- * Linux's drivers/scsi/scsi_transport_fc
- */
-static struct sa_nameval binding_types_table[] = {
-	{ "none",                           0 },
-	{ "wwpn (World Wide Port Name)",    HBA_CAN_BIND_TO_WWPN },
-	{ "wwnn (World Wide Node Name)",    HBA_CAN_BIND_TO_WWNN },
-	{ "port_id (FC Address)",           HBA_CAN_BIND_TO_D_ID },
-	{ NULL,                             0 }
-};
-
-/*
- * Context for LUN binding reader.
- */
-struct binding_context {
-	HBA_HANDLE            oc_handle;
-	int                   oc_kern_hba;  /* kernel HBA number */
-	int                   oc_port;
-	int                   oc_target;
-	int                   oc_lun;
-	u_int32_t             oc_count;
-	u_int32_t             oc_limit;
-	u_int32_t             oc_ver;
-	void                  *oc_entries;
-	HBA_STATUS            oc_status;
-	char                  oc_sg[32];    /* SCSI-generic dev name */
-	HBA_SCSIID            *oc_scp;      /* place for OS device name */
-	struct port_info *oc_rport;    /* target remote port, if known */
-};
-
-/*
- * Get binding capability.
- * We currently don't have a way to get this from the driver.
- * Instead, we hardcode what we know about Linux's capabilities.
- * We don't care which HBA is specified, except to return the correct error.
- */
-HBA_STATUS
-get_binding_capability(HBA_HANDLE handle, HBA_WWN wwn, HBA_BIND_CAPABILITY *cp)
-{
-	struct port_info *pp;
-	int count = 0;
-
-	pp = adapter_get_port_by_wwn(handle, wwn, &count);
-	if (count > 1)
-		return HBA_STATUS_ERROR_AMBIGUOUS_WWN;
-	else if (pp == NULL)
-		return HBA_STATUS_ERROR_ILLEGAL_WWN;
-	*cp = BINDING_CAPABILITIES;
-	return HBA_STATUS_OK;
-}
-
-/*
- * Get binding support.
- */
-HBA_STATUS
-get_binding_support(HBA_HANDLE handle, HBA_WWN wwn, HBA_BIND_CAPABILITY *cp)
-{
-	struct port_info *pp;
-	char dir[50];
-	char bind[50];
-	int count = 0;
-
-	pp = adapter_get_port_by_wwn(handle, wwn, &count);
-	if (count > 1)
-		return HBA_STATUS_ERROR_AMBIGUOUS_WWN;
-	else if (pp == NULL)
-		return HBA_STATUS_ERROR_ILLEGAL_WWN;
-	snprintf(dir, sizeof(dir), SYSFS_HOST_DIR "/host%u", pp->ap_kern_hba);
-	if (sa_sys_read_line(dir, SYSFS_BIND, bind, sizeof(bind)) == 0)
-		sa_enum_encode(binding_types_table, bind, cp);
-	return HBA_STATUS_OK;
-}
-
-/*
- * Set binding support.
- */
-HBA_STATUS
-set_binding_support(HBA_HANDLE handle, HBA_WWN wwn, HBA_BIND_CAPABILITY flags)
-{
-	struct port_info *pp;
-	int count = 0;
-	char dir[50];
-	char buf[50];
-	const char *bind;
-
-	pp = adapter_get_port_by_wwn(handle, wwn, &count);
-	if (count > 1)
-		return HBA_STATUS_ERROR_AMBIGUOUS_WWN;
-	if (pp == NULL)
-		return HBA_STATUS_ERROR_ILLEGAL_WWN;
-	if ((flags & BINDING_CAPABILITIES) != flags)
-		return HBA_STATUS_ERROR_NOT_SUPPORTED;
-	bind = sa_enum_decode(buf, sizeof(buf), binding_types_table, flags);
-	snprintf(dir, sizeof(dir), SYSFS_HOST_DIR "/host%u", pp->ap_kern_hba);
-	if (strstr(bind, "Unknown") != NULL)
-		return HBA_STATUS_ERROR_NOT_SUPPORTED;
-	if (sa_sys_write_line(dir, SYSFS_BIND, bind) == 0)
-		return HBA_STATUS_ERROR_INCAPABLE;
-	return HBA_STATUS_OK;
-}
-
-static int
-get_binding_os_names(struct dirent *dp, void *arg)
-{
-	struct binding_context *cp = arg;
-	char *name = dp->d_name;
-	char *sep;
-
-	sep = strchr(name, ':');
-	if (dp->d_type == DT_LNK && sep != NULL) {
-		*sep = '\0';                /* replace colon */
-		if (strcmp(name, "block") == 0) {
-			snprintf(cp->oc_scp->OSDeviceName,
-				 sizeof(cp->oc_scp->OSDeviceName),
-				 "/dev/%s", sep + 1);
-		} else if (strcmp(name, "scsi_generic") == 0) {
-			snprintf(cp->oc_sg,
-				 sizeof(cp->oc_sg),
-				 "/dev/%s", sep + 1);
-		}
-		*sep = ':';                 /* not really needed */
-	}
-	return 0;
-}
-
-static int
-get_binding_target_mapping(struct dirent *dp, void *ctxt_arg)
-{
-	struct binding_context *cp = ctxt_arg;
-	struct port_info *pp;
-	HBA_FCPSCSIENTRY *sp;
-	HBA_FCPSCSIENTRYV2 *s2p;
-	HBA_SCSIID *scp = NULL;
-	HBA_FCPID *fcp = NULL;
-	HBA_LUID *luid = NULL;
-	char name[50];
-	u_int32_t hba = -1;
-	u_int32_t port = -1;
-	u_int32_t tgt = -1;
-	u_int32_t lun = -1;
-
-	/*
-	 * Parse directory entry name to see if it matches
-	 * <hba>:<port>:<target>:<lun>.
-	 */
-	if (sscanf(dp->d_name, "%u:%u:%u:%u", &hba, &port, &tgt, &lun) != 4)
-		return 0;
-
-	if (hba != cp->oc_kern_hba ||
-	    (port != cp->oc_port && cp->oc_port != -1) ||
-	    (tgt != cp->oc_target && cp->oc_target != -1) ||
-	    (lun != cp->oc_lun && cp->oc_lun != -1)) {
-		return 0;
-	}
-
-	/*
-	 * Name matches.  Add to count and to mapping list if there's room.
-	 */
-	if (cp->oc_count < cp->oc_limit) {
-
-		switch (cp->oc_ver) {
-		case 1:
-			sp = &((HBA_FCPSCSIENTRY *)
-				cp->oc_entries)[cp->oc_count];
-			scp = &sp->ScsiId;
-			fcp = &sp->FcpId;
-			luid = NULL;
-			break;
-		case 2:
-			s2p = &((HBA_FCPSCSIENTRYV2 *)
-				cp->oc_entries)[cp->oc_count];
-			scp = &s2p->ScsiId;
-			fcp = &s2p->FcpId;
-			luid = &s2p->LUID;
-			break;
-		default:
-			fprintf(stderr, "*** Fatal! ***\n");
-			break;
-		}
-		pp = cp->oc_rport;
-		if (pp == NULL)
-			pp = adapter_get_rport_target(cp->oc_handle,
-							port, tgt);
-		if (pp != NULL) {
-			fcp->FcId = pp->ap_attr.PortFcId;
-			fcp->NodeWWN = pp->ap_attr.NodeWWN;
-			fcp->PortWWN = pp->ap_attr.PortWWN;
-			fcp->FcpLun = (HBA_UINT64) lun << 48;
-		}
-
-		/*
-		 * Find OS device name by searching for symlink block:<device>
-		 * and SG name by searching for scsi_generic:<name>
-		 * in device subdirectory.
-		 */
-		snprintf(name, sizeof(name),
-			 SYSFS_LUN_DIR "/%s/device", dp->d_name);
-		cp->oc_sg[0] = '\0';
-		cp->oc_scp = scp;
-		scp->OSDeviceName[0] = '\0';
-		sa_dir_read(name, get_binding_os_names, cp);
-		scp->ScsiBusNumber = hba;
-		scp->ScsiTargetNumber = tgt;
-		scp->ScsiOSLun = lun;
-
-		/*
-		 * find the LUN ID information by using scsi_generic I/O.
-		 */
-		if (luid != NULL && cp->oc_sg[0] != '\0')
-			sg_get_dev_id(cp->oc_sg, luid->buffer,
-					  sizeof(luid->buffer));
-	}
-	cp->oc_count++;
-	return 0;
-}
-
-/*
- * Get FCP target mapping.
- */
-HBA_STATUS
-get_binding_target_mapping_v1(HBA_HANDLE handle, HBA_FCPTARGETMAPPING *map)
-{
-	struct binding_context ctxt;
-	struct adapter_info *ap;
-
-	ap = adapter_open_handle(handle);
-	if (ap == NULL)
-		return HBA_STATUS_ERROR_INVALID_HANDLE;
-	memset(&ctxt, 0, sizeof(ctxt));
-	ctxt.oc_handle = handle;
-	ctxt.oc_kern_hba = ap->ad_kern_index;
-	ctxt.oc_port = -1;
-	ctxt.oc_target = -1;
-	ctxt.oc_lun = -1;
-	ctxt.oc_limit = map->NumberOfEntries;
-	ctxt.oc_ver = 1;
-	ctxt.oc_entries = map->entry;
-	ctxt.oc_status = HBA_STATUS_OK;
-	memset(map->entry, 0, sizeof(map->entry[0]) * ctxt.oc_limit);
-	sa_dir_read(SYSFS_LUN_DIR, get_binding_target_mapping, &ctxt);
-	map->NumberOfEntries = ctxt.oc_count;
-	if (ctxt.oc_status == HBA_STATUS_OK && ctxt.oc_count > ctxt.oc_limit)
-		ctxt.oc_status = HBA_STATUS_ERROR_MORE_DATA;
-	return ctxt.oc_status;
-}
-
-/*
- * Get FCP target mapping.
- */
-HBA_STATUS
-get_binding_target_mapping_v2(HBA_HANDLE handle, HBA_WWN wwn,
-			       HBA_FCPTARGETMAPPINGV2 *map)
-{
-	struct binding_context ctxt;
-	struct adapter_info *ap;
-	struct port_info *pp;
-
-	pp = adapter_get_port_by_wwn(handle, wwn, NULL);
-	if (pp == NULL)
-		return HBA_STATUS_ERROR_INVALID_HANDLE;
-	ap = pp->ap_adapt;
-	if (ap == NULL)
-		return HBA_STATUS_ERROR_INVALID_HANDLE;
-	memset(&ctxt, 0, sizeof(ctxt));
-	ctxt.oc_handle = handle;
-	ctxt.oc_kern_hba = ap->ad_kern_index;
-	ctxt.oc_port = pp->ap_index;
-	ctxt.oc_target = -1;
-	ctxt.oc_lun = -1;
-	ctxt.oc_limit = map->NumberOfEntries;
-	ctxt.oc_ver = 2;
-	ctxt.oc_entries = map->entry;
-	ctxt.oc_status = HBA_STATUS_OK;
-	memset(map->entry, 0, sizeof(map->entry[0]) * ctxt.oc_limit);
-	sa_dir_read(SYSFS_LUN_DIR, get_binding_target_mapping, &ctxt);
-	map->NumberOfEntries = ctxt.oc_count;
-	return ctxt.oc_status;
-}
-
-/*
- * Get LUN scsi-generic device name.
- */
-int
-get_binding_sg_name(struct port_info *lp, HBA_WWN disc_wwpn,
-		     HBA_UINT64 fc_lun, char *buf, size_t len)
-{
-	struct binding_context ctxt;
-	struct port_info *rp;
-	HBA_FCPSCSIENTRYV2 entry;
-
-	/*
-	 * find discovered (remote) port.
-	 */
-	rp = adapter_get_rport_by_wwn(lp, disc_wwpn);
-	if (rp == NULL)
-		return HBA_STATUS_ERROR_ILLEGAL_WWN;
-
-	/*
-	 * Check for LUN more than 1023 or multi-level.
-	 */
-	if (fc_lun & ((0xfc01ULL << 48) - 1))
-		return HBA_STATUS_ERROR;
-	memset(&ctxt, 0, sizeof(ctxt));
-	memset(&entry, 0, sizeof(entry));
-	ctxt.oc_rport = rp;
-	ctxt.oc_kern_hba = rp->ap_kern_hba;
-	ctxt.oc_port = rp->ap_index;
-	ctxt.oc_target = rp->ap_scsi_target;
-	if (ctxt.oc_target == -1)
-		return ENOENT;
-	ctxt.oc_lun = fc_lun >> 48;
-	ctxt.oc_limit = 1;
-	ctxt.oc_ver = 1;
-	ctxt.oc_entries = &entry;
-	sa_dir_read(SYSFS_LUN_DIR, get_binding_target_mapping, &ctxt);
-	if (ctxt.oc_count != 1)
-		return ENOENT;
-	strncpy(buf, ctxt.oc_sg, len);
-	return 0;
-}
diff --git a/libhbalinux/bind_impl.h b/libhbalinux/bind_impl.h
deleted file mode 100644
index 7bcff02..0000000
--- a/libhbalinux/bind_impl.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2008, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU Lesser General Public License,
- * version 2.1, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#ifndef _BIND_IMPL_H_
-#define _BIND_IMPL_H_
-
-HBA_STATUS get_binding_capability(HBA_HANDLE, HBA_WWN, HBA_BIND_CAPABILITY *);
-HBA_STATUS get_binding_support(HBA_HANDLE, HBA_WWN, HBA_BIND_CAPABILITY *);
-HBA_STATUS set_binding_support(HBA_HANDLE, HBA_WWN, HBA_BIND_CAPABILITY);
-HBA_STATUS get_binding_target_mapping_v1(HBA_HANDLE, HBA_FCPTARGETMAPPING *);
-HBA_STATUS get_binding_target_mapping_v2(HBA_HANDLE, HBA_WWN,
-					  HBA_FCPTARGETMAPPINGV2 *);
-int get_binding_sg_name(struct port_info *,
-			HBA_WWN, HBA_UINT64, char *, size_t);
-
-#endif /* _BIND_IMPL_H_ */
diff --git a/libhbalinux/lib.c b/libhbalinux/lib.c
deleted file mode 100644
index 623b126..0000000
--- a/libhbalinux/lib.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (c) 2008, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU Lesser General Public License,
- * version 2.1, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#define _XOPEN_SOURCE 500        /* for strptime() */
-#include "utils.h"
-#include "api_lib.h"
-#include "adapt_impl.h"
-#include "bind_impl.h"
-
-/**
- * Return the version of the SNIA HBA-API supported by this library.
- */
-static HBA_UINT32 get_library_version()
-{
-	return HBA_LIBVERSION;
-}
-
-/*
- * When HBA_GetVendorLibraryAttributes() is called,
- * it does not dispatch to the library entry point at
- * .GetVendorLibraryAttributesHandler. Thus this
- * routine can never be entered. -[sma]
- */
-#if 0
-/**
- * Get the library attributes.
- * @param ap library attributes pointer.
- * @returns 0 or error code.
- */
-static HBA_STATUS get_vendor_lib_attrs(HBA_LIBRARYATTRIBUTES *ap)
-{
-	memset(ap, 0, sizeof(*ap));
-	if (strptime(BUILD_DATE, "%Y/%m/%d %T %Z", &ap->build_date) == NULL)
-		memset(&ap->build_date, 0, sizeof(ap->build_date));
-	strcpy(ap->VName, HBA_API_VENDOR);
-	strcpy(ap->VVersion, HBA_API_VERSION);
-	return HBA_STATUS_OK;
-}
-#endif
-
-/*
- * initialize the library after load.
- */
-static HBA_STATUS load_library(void)
-{
-	adapter_init();
-	return HBA_STATUS_OK;
-}
-
-static HBA_STATUS free_library(void)
-{
-	adapter_shutdown();
-	adapter_destroy_all();
-	return HBA_STATUS_OK;
-}
-
-static HBA_ENTRYPOINTSV2 vendor_lib_entrypoints = {
-    .GetVersionHandler =                       get_library_version,
-    .LoadLibraryHandler =                      load_library,
-    .FreeLibraryHandler =                      free_library,
-    .GetNumberOfAdaptersHandler =              adapter_get_count,
-    .GetAdapterNameHandler =                   adapter_get_name,
-    .OpenAdapterHandler =                      adapter_open,
-    .CloseAdapterHandler =                     adapter_close,
-    .GetAdapterAttributesHandler =             adapter_get_attr,
-    .GetAdapterPortAttributesHandler =         adapter_get_port_attr,
-    .GetPortStatisticsHandler =                get_port_statistics,
-    .GetDiscoveredPortAttributesHandler =      adapter_get_rport_attr,
-
-    .GetPortAttributesByWWNHandler =           NULL,
-					/* adapter_get_port_attr_by_wwn, */
-    /* Next function deprecated but still supported */
-    .SendCTPassThruHandler =                   NULL,
-    .RefreshInformationHandler =               NULL,
-    .ResetStatisticsHandler =                  NULL,
-    /* Next function deprecated but still supported */
-    .GetFcpTargetMappingHandler =              get_binding_target_mapping_v1,
-    /* Next function depricated but still supported */
-    .GetFcpPersistentBindingHandler =          NULL,
-    .GetEventBufferHandler =                   NULL,
-    .SetRNIDMgmtInfoHandler =                  NULL,
-    .GetRNIDMgmtInfoHandler =                  NULL,
-    /* Next function deprecated but still supported */
-    .SendRNIDHandler =                         NULL,
-    .ScsiInquiryHandler =                      scsi_inquiry_v1,
-    .ReportLUNsHandler =                       scsi_report_luns_v1,
-    .ReadCapacityHandler =                     scsi_read_capacity_v1,
-
-    /* V2 handlers */
-    .OpenAdapterByWWNHandler =                 NULL,
-					/* adapter_open_by_wwn, */
-    .GetFcpTargetMappingV2Handler =            get_binding_target_mapping_v2,
-    .SendCTPassThruV2Handler =                 NULL,
-    .RefreshAdapterConfigurationHandler =      NULL,
-    .GetBindingCapabilityHandler =             NULL,
-					/* get_binding_capability, */
-    .GetBindingSupportHandler =                NULL,
-					/* get_binding_support, */
-    .SetBindingSupportHandler =                NULL,
-					/* set_binding_support, */
-    .SetPersistentBindingV2Handler =           NULL,
-    .GetPersistentBindingV2Handler =           NULL,
-    .RemovePersistentBindingHandler =          NULL,
-    .RemoveAllPersistentBindingsHandler =      NULL,
-    .SendRNIDV2Handler =                       NULL,
-    .ScsiInquiryV2Handler =                    scsi_inquiry_v2,
-    .ScsiReportLUNsV2Handler =                 scsi_report_luns_v2,
-    .ScsiReadCapacityV2Handler =               scsi_read_capacity_v2,
-    .GetVendorLibraryAttributesHandler =       NULL,
-					/* get_vendor_lib_attrs, */
-    .RemoveCallbackHandler =                   NULL,
-    .RegisterForAdapterAddEventsHandler =      NULL,
-    .RegisterForAdapterEventsHandler =         NULL,
-    .RegisterForAdapterPortEventsHandler =     NULL,
-    .RegisterForAdapterPortStatEventsHandler = NULL,
-    .RegisterForTargetEventsHandler =          NULL,
-    .RegisterForLinkEventsHandler =            NULL,
-    .SendRPLHandler =                          NULL,
-    .SendRPSHandler =                          NULL,
-    .SendSRLHandler =                          NULL,
-    .SendLIRRHandler =                         NULL,
-    .GetFC4StatisticsHandler =                 get_port_fc4_statistics,
-    .GetFCPStatisticsHandler =                 NULL,
-    .SendRLSHandler =                          NULL,
-};
-
-/**
- * Function called by a version 1 common HBAAPI library to get our entry points.
- *
- * @arg ep pointer to entrypoints structure where we store our
- *  function pointers.
- * @returns HBA_STATUS.
- */
-HBA_STATUS HBA_RegisterLibrary(HBA_ENTRYPOINTS *ep)
-{
-	memcpy(ep, &vendor_lib_entrypoints, sizeof(HBA_ENTRYPOINTS));
-	return HBA_STATUS_OK;
-}
-
-/**
- * Function called by the common HBAAPI library to get our entry points.
- *
- * @arg ep pointer to entrypoints structure where we store our
- *  function pointers.
- * @returns HBA_STATUS.
- */
-HBA_STATUS HBA_RegisterLibraryV2(HBA_ENTRYPOINTSV2 *ep)
-{
-	*ep = vendor_lib_entrypoints;  /* structure copy */
-	return HBA_STATUS_OK;
-}
-
diff --git a/libhbalinux/lport.c b/libhbalinux/lport.c
deleted file mode 100644
index 9c47887..0000000
--- a/libhbalinux/lport.c
+++ /dev/null
@@ -1,545 +0,0 @@
-/*
- * Copyright (c) 2008, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU Lesser General Public License,
- * version 2.1, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include "utils.h"
-#include "api_lib.h"
-#include "adapt_impl.h"
-
-#ifndef HBA_STATUS_ERROR_ILLEGAL_FCID
-#define HBA_STATUS_ERROR_ILLEGAL_FCID 33	/* defined after HBA-API 2.2 */
-#endif
-#define SEND_CT_TIMEOUT		(3 * 1000)	/* timeout in milliseconds */
-
-/*
- * The following are temporary settings until we can find a way to
- * collect these information.
- */
-#define HBA_MODEL               "(Unknown)"
-#define HBA_ROM_VERSION         "(None)"
-#define HBA_FW_VERSION          "(None)"
-#define HBA_VENDOR_SPECIFIC_ID  123456
-
-/*
- * Convert fc_port_type values to ascii string name.
- * (This table is copied from scsi_transport_fc.c).
- */
-static struct {
-	enum fc_port_type	value;
-	char			*name;
-} port_types_table[] = {
-    { FC_PORTTYPE_UNKNOWN,     "Unknown" },
-    { FC_PORTTYPE_OTHER,       "Other" },
-    { FC_PORTTYPE_NOTPRESENT,  "Not Present" },
-    { FC_PORTTYPE_NPORT,       "NPort (fabric via point-to-point)" },
-    { FC_PORTTYPE_NLPORT,      "NLPort (fabric via loop)" },
-    { FC_PORTTYPE_LPORT,       "LPort (private loop)" },
-    { FC_PORTTYPE_PTP,         "Point-To-Point (direct nport connection)" },
-    { FC_PORTTYPE_NPIV,        "NPIV VPORT" },
-};
-fc_enum_name_search(port_type, fc_port_type, port_types_table)
-#define FC_PORTTYPE_MAX_NAMELEN         50
-
-/*
- * table of /sys port state strings to HBA-API values.
- */
-struct sa_nameval port_states_table[] = {
-	{ "Not Present",    HBA_PORTSTATE_UNKNOWN },
-	{ "Online",         HBA_PORTSTATE_ONLINE },
-	{ "Offline",        HBA_PORTSTATE_OFFLINE },
-	{ "Blocked",        HBA_PORTSTATE_UNKNOWN },
-	{ "Bypassed",       HBA_PORTSTATE_BYPASSED },
-	{ "Diagnostics",    HBA_PORTSTATE_DIAGNOSTICS },
-	{ "Linkdown",       HBA_PORTSTATE_LINKDOWN },
-	{ "Error",          HBA_PORTSTATE_ERROR },
-	{ "Loopback",       HBA_PORTSTATE_LOOPBACK },
-	{ "Deleted",        HBA_PORTSTATE_UNKNOWN },
-	{ NULL, 0 }
-};
-
-/*
- * table of /sys port speed strings to HBA-API values.
- */
-struct sa_nameval port_speeds_table[] = {
-	{ "10 Gbit",        HBA_PORTSPEED_10GBIT },
-	{ "2 Gbit",         HBA_PORTSPEED_2GBIT },
-	{ "1 Gbit",         HBA_PORTSPEED_1GBIT },
-	{ "Not Negotiated", HBA_PORTSPEED_NOT_NEGOTIATED },
-	{ "Unknown",        HBA_PORTSPEED_UNKNOWN },
-	{ NULL, 0 }
-};
-
-/*
- * Code for OpenFC-supported adapters.
- */
-
-static int
-counting_rports(struct dirent *dp, void *arg)
-{
-	int *count = (int *)arg;
-
-	if (!strstr(dp->d_name, "rport-"))
-		return HBA_STATUS_OK;
-	(*count)++;
-	return HBA_STATUS_OK;
-}
-
-static int
-sysfs_scan(struct dirent *dp, void *arg)
-{
-	int lport_count = 0;
-	HBA_ADAPTERATTRIBUTES *atp;
-	HBA_PORTATTRIBUTES *pap;
-	HBA_WWN wwnn;
-	struct hba_info hba_info;
-	struct adapter_info *ap;
-	struct port_info *pp;
-	char host_dir[80], hba_dir[80], drv_dir[80];
-	char ifname[20], buf[256];
-	char *driverName;
-	int data[32], rc, i;
-
-	/* Found a local port! */
-	lport_count++;
-
-	/*
-	 * Create a new HBA entry (ap) for the local port
-	 * We will create a new HBA entry for each local port.
-	 */
-	ap = malloc(sizeof(*ap));
-	if (!ap) {
-		fprintf(stderr, "%s: malloc failed, errno=0x%x\n",
-			__func__, errno);
-		return HBA_STATUS_ERROR;
-	}
-	memset(ap, 0, sizeof(*ap));
-	ap->ad_kern_index = atoi(dp->d_name + sizeof("host") - 1);
-	ap->ad_port_count = 1;
-
-	/* atp points to the HBA attributes structure */
-	atp = &ap->ad_attr;
-
-	/*
-	 * Create a new local port entry
-	 */
-	pp = malloc(sizeof(*pp));
-	if (pp == NULL) {
-		fprintf(stderr,
-			"%s: malloc for local port %d failed,"
-			" errno=0x%x\n", __func__,
-			ap->ad_port_count - 1, errno);
-		return HBA_STATUS_ERROR;
-	}
-
-	memset(pp, 0, sizeof(*pp));
-	pp->ap_adapt = ap;
-	pp->ap_index = ap->ad_port_count - 1;
-	pp->ap_kern_hba = atoi(dp->d_name + sizeof("host") - 1);
-
-	/* pap points to the local port attributes structure */
-	pap = &pp->ap_attr;
-
-	/* Construct the host directory name from the input name */
-	snprintf(host_dir, sizeof(host_dir),
-		SYSFS_HOST_DIR "/%s", dp->d_name);
-
-	/* Get the ifname from the symbolic_name */
-	rc = sa_sys_read_line(host_dir, "symbolic_name", buf, sizeof(buf));
-	sa_strncpy_safe(ifname, sizeof(ifname),
-			strstr(buf, "over") + 5, sizeof(ifname));
-	snprintf(hba_dir, sizeof(hba_dir),
-		 SYSFS_HBA_DIR "/%s/device", ifname);
-
-	/*
-	 * Save the host directory and the hba directory
-	 * in local port structure
-	 */
-	sa_strncpy_safe(pp->host_dir, sizeof(pp->host_dir),
-			host_dir, sizeof(host_dir));
-
-	/* Get PortSymbolicName */
-	sa_strncpy_safe(pap->PortSymbolicName, sizeof(pap->PortSymbolicName),
-			buf, sizeof(buf));
-
-	/* Get NodeWWN */
-	rc = sys_read_wwn(pp->host_dir, "node_name", &wwnn);
-	memcpy(&pap->NodeWWN, &wwnn, sizeof(wwnn));
-
-	/* Get PortWWN */
-	rc = sys_read_wwn(pp->host_dir, "port_name", &pap->PortWWN);
-
-	/* Get PortFcId */
-	rc = sa_sys_read_u32(pp->host_dir, "port_id", &pap->PortFcId);
-
-	/* Get PortType */
-	rc = sa_sys_read_line(pp->host_dir, "port_type", buf, sizeof(buf));
-	pap->PortType = get_fc_port_type_value(buf);
-
-	/* Get PortState */
-	rc = sa_sys_read_line(pp->host_dir, "port_state", buf, sizeof(buf));
-	rc = sa_enum_encode(port_states_table, buf, &pap->PortState);
-
-	/* Get PortSpeed */
-	rc = sa_sys_read_line(pp->host_dir, "speed", buf, sizeof(buf));
-	rc = sa_enum_encode(port_speeds_table, buf, &pap->PortSpeed);
-
-	/* Get PortSupportedSpeed */
-	rc = sa_sys_read_line(pp->host_dir, "supported_speed",
-				buf, sizeof(buf));
-	rc = sa_enum_encode(port_speeds_table, buf, &pap->PortSupportedSpeed);
-
-	/* Get PortMaxFrameSize */
-	rc = sa_sys_read_line(pp->host_dir, "maxframe_size", buf, sizeof(buf));
-	sscanf(buf, "%d", &pap->PortMaxFrameSize);
-
-	/* Get PortSupportedFc4Types */
-	rc = sa_sys_read_line(pp->host_dir, "supported_fc4s", buf, sizeof(buf));
-	sscanf(buf, "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x "
-		    "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x "
-		    "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x "
-		    "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
-		&data[0], &data[1], &data[2], &data[3], &data[4], &data[5],
-		&data[6], &data[7], &data[8], &data[9], &data[10], &data[11],
-		&data[12], &data[13], &data[14], &data[15], &data[16],
-		&data[17], &data[18], &data[19], &data[20], &data[21],
-		&data[22], &data[23], &data[24], &data[25], &data[26],
-		&data[27], &data[28], &data[29], &data[30], &data[31]);
-	for (i = 0; i < 32; i++)
-		pap->PortSupportedFc4Types.bits[i] = data[i];
-
-	/* Get PortActiveFc4Types */
-	rc = sa_sys_read_line(pp->host_dir, "active_fc4s", buf, sizeof(buf));
-	sscanf(buf, "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x "
-		    "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x "
-		    "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x "
-		    "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
-		&data[0], &data[1], &data[2], &data[3], &data[4], &data[5],
-		&data[6], &data[7], &data[8], &data[9], &data[10], &data[11],
-		&data[12], &data[13], &data[14], &data[15], &data[16],
-		&data[17], &data[18], &data[19], &data[20], &data[21],
-		&data[22], &data[23], &data[24], &data[25], &data[26],
-		&data[27], &data[28], &data[29], &data[30], &data[31]);
-	for (i = 0; i < 32; i++)
-		pap->PortActiveFc4Types.bits[i] = data[i];
-
-	/* Get FabricName */
-	rc = sys_read_wwn(pp->host_dir, "fabric_name", &pap->FabricName);
-
-	/* Get PortSupportedClassofService */
-	rc = sa_sys_read_line(pp->host_dir, "supported_classes",
-				buf, sizeof(buf));
-	pap->PortSupportedClassofService = *(strstr(buf, "Class") + 6) - '0';
-
-	/* Get OSDeviceName */
-	sa_strncpy_safe(pap->OSDeviceName, sizeof(pap->OSDeviceName),
-			dp->d_name, sizeof(dp->d_name));
-
-	/* Get NumberofDiscoveredPorts */
-	snprintf(buf, sizeof(buf), "%s/device", pp->host_dir);
-	sa_dir_read(buf, counting_rports, &pap->NumberofDiscoveredPorts);
-
-	/*
-	 * Add the local port structure into local port table within
-	 * the HBA structure.
-	 */
-	if (sa_table_insert(&ap->ad_ports, pp->ap_index, pp) < 0) {
-		fprintf(stderr,
-			"%s: insert of HBA %d port %d failed\n",
-			__func__, ap->ad_kern_index, pp->ap_index);
-		free(pp);
-	}
-
-	/* Create adapter name */
-	snprintf(buf, sizeof(buf), "fcoe:%s", ifname);
-	ap->ad_name = strdup(buf);
-
-	/* Get vendor_id */
-	rc = sa_sys_read_u32(hba_dir, "vendor", &hba_info.vendor_id);
-
-	/* Get device_id */
-	rc = sa_sys_read_u32(hba_dir, "device", &hba_info.device_id);
-
-	/* Get subsystem_vendor_id */
-	rc = sa_sys_read_u32(hba_dir, "subsystem_vendor",
-				&hba_info.subsystem_vendor_id);
-
-	/* Get subsystem_device_id */
-	rc = sa_sys_read_u32(hba_dir, "subsystem_device",
-				&hba_info.subsystem_device_id);
-
-	/* Get device_class */
-	rc = sa_sys_read_u32(hba_dir, "class", &hba_info.device_class);
-	hba_info.device_class = hba_info.device_class>>8;
-
-	/*
-	 * Get Hardware Information via PCI Library
-	 */
-	i = readlink(hba_dir, buf, sizeof(buf));
-	if (i < 0) {
-		printf("readlink %s failed\n", hba_dir);
-		return HBA_STATUS_ERROR;
-	}
-	buf[i] = '\0';
-	sscanf(strrchr(buf, '/') + 1, "%x:%x:%x.%x",
-		&hba_info.domain, &hba_info.bus,
-		&hba_info.dev, &hba_info.func);
-	rc = find_pci_device(&hba_info);
-	if (rc != HBA_STATUS_OK)
-		return rc;
-
-	/* Get Number of Ports */
-	atp->NumberOfPorts = hba_info.NumberOfPorts;
-
-	/* Get Manufacturer */
-	sa_strncpy_safe(atp->Manufacturer, sizeof(atp->Manufacturer),
-			hba_info.Manufacturer, sizeof(hba_info.Manufacturer));
-
-	/* Get SerialNumber */
-	sa_strncpy_safe(atp->SerialNumber, sizeof(atp->SerialNumber),
-			hba_info.SerialNumber, sizeof(hba_info.SerialNumber));
-
-	/* Get Model (TODO) */
-	sa_strncpy_safe(atp->Model, sizeof(atp->Model),
-			HBA_MODEL, sizeof(HBA_MODEL));
-
-	/* Get ModelDescription */
-	sa_strncpy_safe(atp->ModelDescription, sizeof(atp->ModelDescription),
-			hba_info.ModelDescription,
-			sizeof(hba_info.ModelDescription));
-
-	/* Get HardwareVersion */
-	sa_strncpy_safe(atp->HardwareVersion, sizeof(atp->HardwareVersion),
-			hba_info.HardwareVersion,
-			sizeof(hba_info.HardwareVersion));
-
-	/* Get OptionROMVersion (TODO) */
-	sa_strncpy_safe(atp->OptionROMVersion, sizeof(atp->OptionROMVersion),
-			HBA_ROM_VERSION, sizeof(HBA_ROM_VERSION));
-
-	/* Get FirmwareVersion (TODO) */
-	sa_strncpy_safe(atp->FirmwareVersion, sizeof(atp->FirmwareVersion),
-			HBA_FW_VERSION, sizeof(HBA_FW_VERSION));
-
-	/* Get VendorSpecificID (TODO) */
-	atp->VendorSpecificID = HBA_VENDOR_SPECIFIC_ID;
-
-	/* Get DriverVersion */
-	rc = sa_sys_read_line(hba_dir, SYSFS_MODULE_VER,
-			atp->DriverVersion, sizeof(atp->DriverVersion));
-
-	/* Get NodeSymbolicName */
-	sa_strncpy_safe(atp->NodeSymbolicName, sizeof(atp->NodeSymbolicName),
-			ap->ad_name, sizeof(atp->NodeSymbolicName));
-
-	/* Get NodeWWN - The NodeWWN is the same as
-	 *               the NodeWWN of the local port.
-	 */
-	memcpy((char *)&atp->NodeWWN, (char *)&pap->NodeWWN,
-		sizeof(pap->NodeWWN));
-
-	/* Get DriverName */
-	snprintf(drv_dir, sizeof(drv_dir), "%s" SYSFS_MODULE , hba_dir);
-	i = readlink(drv_dir, buf, sizeof(buf));
-	if (i < 0) {
-		printf("Fatal! readlink %s failed\n", drv_dir);
-		return HBA_STATUS_ERROR;
-	}
-	buf[i] = '\0';
-	if (!strstr(buf, "module")) {
-		/*
-		 * Does not find "module" in the string.
-		 * This should not happen. In this case, set
-		 * the driver name to "Unknown".
-		 */
-		driverName = "Unknown";
-	} else
-		driverName = strstr(buf, "module") + 7;
-	sa_strncpy_safe(atp->DriverName, sizeof(atp->DriverName),
-			driverName, sizeof(atp->DriverName));
-
-	/*
-	 * Give HBA to library
-	 */
-	rc = adapter_create(ap);
-	if (rc != HBA_STATUS_OK) {
-		fprintf(stderr, "%s: adapter_create failed, status=%d\n",
-			__func__, rc);
-		adapter_destroy(ap);      /* free adapter and ports */
-	}
-
-	return HBA_STATUS_OK;
-}
-
-void
-copy_wwn(HBA_WWN *dest, fc_wwn_t src)
-{
-	dest->wwn[0] = (u_char) (src >> 56);
-	dest->wwn[1] = (u_char) (src >> 48);
-	dest->wwn[2] = (u_char) (src >> 40);
-	dest->wwn[3] = (u_char) (src >> 32);
-	dest->wwn[4] = (u_char) (src >> 24);
-	dest->wwn[5] = (u_char) (src >> 16);
-	dest->wwn[6] = (u_char) (src >> 8);
-	dest->wwn[7] = (u_char) src;
-}
-
-/* Test for a non-zero WWN */
-int
-is_wwn_nonzero(HBA_WWN *wwn)
-{
-	return (wwn->wwn[0] | wwn->wwn[1] | wwn->wwn[2] | wwn->wwn[3] |
-		wwn->wwn[4] | wwn->wwn[5] | wwn->wwn[6] | wwn->wwn[7]) != 0;
-}
-
-int
-sys_read_wwn(const char *dir, const char *file, HBA_WWN *wwn)
-{
-	int rc;
-	u_int64_t val;
-
-	rc = sa_sys_read_u64(dir, file, &val);
-	if (rc == 0)
-		copy_wwn(wwn, val);
-	return rc;
-}
-
-/* Port Statistics */
-HBA_STATUS
-sysfs_get_port_stats(char *dir, HBA_PORTSTATISTICS *sp)
-{
-	int rc;
-
-	rc  = sa_sys_read_u64(dir, "seconds_since_last_reset",
-				(u_int64_t *)&sp->SecondsSinceLastReset);
-	rc |= sa_sys_read_u64(dir, "tx_frames", (u_int64_t *)&sp->TxFrames);
-	rc |= sa_sys_read_u64(dir, "tx_words", (u_int64_t *)&sp->TxWords);
-	rc |= sa_sys_read_u64(dir, "rx_frames", (u_int64_t *)&sp->RxFrames);
-	rc |= sa_sys_read_u64(dir, "rx_words", (u_int64_t *)&sp->RxWords);
-	rc |= sa_sys_read_u64(dir, "lip_count", (u_int64_t *)&sp->LIPCount);
-	rc |= sa_sys_read_u64(dir, "nos_count", (u_int64_t *)&sp->NOSCount);
-	rc |= sa_sys_read_u64(dir, "error_frames",
-				(u_int64_t *)&sp->ErrorFrames);
-	rc |= sa_sys_read_u64(dir, "dumped_frames",
-				(u_int64_t *)&sp->DumpedFrames);
-	rc |= sa_sys_read_u64(dir, "link_failure_count",
-				(u_int64_t *)&sp->LinkFailureCount);
-	rc |= sa_sys_read_u64(dir, "loss_of_sync_count",
-				(u_int64_t *)&sp->LossOfSyncCount);
-	rc |= sa_sys_read_u64(dir, "loss_of_signal_count",
-				(u_int64_t *)&sp->LossOfSignalCount);
-	rc |= sa_sys_read_u64(dir, "prim_seq_protocol_err_count",
-				(u_int64_t *)&sp->PrimitiveSeqProtocolErrCount);
-	rc |= sa_sys_read_u64(dir, "invalid_tx_word_count",
-				(u_int64_t *)&sp->InvalidTxWordCount);
-	rc |= sa_sys_read_u64(dir, "invalid_crc_count",
-				(u_int64_t *)&sp->InvalidCRCCount);
-
-	return rc;
-}
-
-/* Port FC-4 Statistics */
-HBA_STATUS
-sysfs_get_port_fc4stats(char *dir, HBA_FC4STATISTICS *fc4sp)
-{
-	int rc;
-
-	rc  = sa_sys_read_u64(dir, "fcp_input_requests",
-				(u_int64_t *)&fc4sp->InputRequests);
-	rc |= sa_sys_read_u64(dir, "fcp_output_requests",
-				(u_int64_t *)&fc4sp->OutputRequests);
-	rc |= sa_sys_read_u64(dir, "fcp_control_requests",
-				(u_int64_t *)&fc4sp->ControlRequests);
-	rc |= sa_sys_read_u64(dir, "fcp_input_megabytes",
-				(u_int64_t *)&fc4sp->InputMegabytes);
-	rc |= sa_sys_read_u64(dir, "fcp_output_megabytes",
-				(u_int64_t *)&fc4sp->OutputMegabytes);
-
-	return rc;
-}
-/*
- * Open device and read adapter info if available.
- */
-void
-adapter_init(void)
-{
-	sa_dir_read(SYSFS_HOST_DIR, sysfs_scan, NULL);
-}
-
-void
-adapter_shutdown(void)
-{
-}
-
-HBA_STATUS
-get_port_statistics(HBA_HANDLE handle, HBA_UINT32 port, HBA_PORTSTATISTICS *sp)
-{
-	struct port_info *pp;
-	char dir[80];
-	int rc;
-
-	memset(sp, 0xff, sizeof(*sp)); /* unsupported statistics give -1 */
-	pp = adapter_get_port(handle, port);
-	if (pp == NULL) {
-		fprintf(stderr, "%s: lookup failed. handle 0x%x port 0x%x\n",
-			__func__, handle, port);
-		return HBA_STATUS_ERROR;
-	}
-
-	snprintf(dir, sizeof(dir), "%s/statistics", pp->host_dir);
-	rc = sysfs_get_port_stats(dir, sp);
-	if (rc != 0) {
-		fprintf(stderr, "%s: sysfs_get_port_stats() failed,"
-			" hba index=%d port index=%d, -rc=0x%x\n",
-			__func__, pp->ap_adapt->ad_kern_index,
-			pp->ap_index, -rc);
-		return HBA_STATUS_ERROR;
-	}
-	return HBA_STATUS_OK;
-}
-
-/*
- * Get FC4 statistics.
- */
-HBA_STATUS
-get_port_fc4_statistics(HBA_HANDLE handle, HBA_WWN wwn,
-		       HBA_UINT8 fc4_type, HBA_FC4STATISTICS *sp)
-{
-	struct port_info *pp;
-	char dir[80];
-	int count;
-	int rc;
-
-	memset(sp, 0xff, sizeof(*sp)); /* unsupported statistics give -1 */
-
-	pp = adapter_get_port_by_wwn(handle, wwn, &count);
-	if (count > 1)
-		return HBA_STATUS_ERROR_AMBIGUOUS_WWN;
-	else if (pp == NULL)
-		return HBA_STATUS_ERROR_ILLEGAL_WWN;
-
-	snprintf(dir, sizeof(dir), "%s/statistics", pp->host_dir);
-	rc = sysfs_get_port_fc4stats(dir, sp);
-	if (rc != 0) {
-		fprintf(stderr, "%s: sysfs_get_port_fc4stats() failed,"
-			" hba index=%d port index=%d, -rc=0x%x\n",
-			__func__, pp->ap_adapt->ad_kern_index,
-			pp->ap_index, -rc);
-		return HBA_STATUS_ERROR;
-	}
-	return HBA_STATUS_OK;
-}
-
diff --git a/libhbalinux/pci.c b/libhbalinux/pci.c
deleted file mode 100644
index 94032dd..0000000
--- a/libhbalinux/pci.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright (c) 2008, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU Lesser General Public License,
- * version 2.1, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include "utils.h"
-#include "adapt_impl.h"
-#include <linux/pci_regs.h>
-#include <pciaccess.h>
-#include <byteswap.h>
-
-static void
-get_device_serial_number(struct pci_device *dev, struct hba_info *hba_info)
-{
-	pciaddr_t offset;
-	u_int32_t pcie_cap_header;
-	u_int16_t pcie_cap_id;
-	u_int16_t status;
-	u_int8_t cap_ptr;
-	u_int32_t dword_low = 0;
-	u_int32_t dword_high = 0;
-	int rc;
-
-	/*
-	 * Read the Status Register in the PCIe configuration
-	 * header space to see if the PCI Capability List is
-	 * supported by this device.
-	 */
-	rc = pci_device_cfg_read_u16(dev, &status, PCI_STATUS);
-	if (rc) {
-		fprintf(stderr, "Failed reading PCI Status Register\n");
-		return;
-	}
-	if (!(status & PCI_STATUS_CAP_LIST)) {
-		printf("PCI capabilities are not supported\n");
-		return;
-	}
-
-	/*
-	 * Read the offset (cap_ptr) of first entry in the capability list in
-	 * the PCI configuration space.
-	 */
-	rc = pci_device_cfg_read_u8(dev, &cap_ptr, PCI_CAPABILITY_LIST);
-	if (rc) {
-		fprintf(stderr,
-			"Failed reading PCI Capability List Register\n");
-		return;
-	}
-	offset = cap_ptr;
-
-	/* Search for the PCIe capability */
-	while (offset) {
-		u_int8_t cap_id;
-		u_int8_t next_cap;
-
-		rc = pci_device_cfg_read_u8(dev, &cap_id,
-					    offset + PCI_CAP_LIST_ID);
-		if (rc) {
-			fprintf(stderr,
-				"Failed reading capability ID at 0x%lx\n",
-				offset + PCI_CAP_LIST_ID);
-			return;
-		}
-
-		if (cap_id != PCI_CAP_ID_EXP) {
-			rc = pci_device_cfg_read_u8(dev, &next_cap,
-						    offset + PCI_CAP_LIST_NEXT);
-			if (rc) {
-				fprintf(stderr,
-					"Failed reading next capability "
-					"offset at 0x%lx\n",
-					offset + PCI_CAP_LIST_NEXT);
-				return;
-			}
-			offset = (pciaddr_t)next_cap;
-			continue;
-		}
-
-		/*
-		 * PCIe Capability Structure exists!
-		 */
-
-		/*
-		 * The first PCIe extended capability is located at
-		 * offset 0x100 in the device configuration space.
-		 */
-		offset = 0x100;
-
-		do {
-			rc = pci_device_cfg_read_u32(dev, &pcie_cap_header,
-						     offset);
-			if (rc) {
-				fprintf(stderr,
-					"Failed reading PCIe config header\n");
-				return;
-			}
-
-			/* Get the PCIe Extended Capability ID */
-			pcie_cap_id = pcie_cap_header & 0xffff;
-
-			if (pcie_cap_id != PCI_EXT_CAP_ID_DSN) {
-				/* Get the offset of the next capability */
-				offset = (pciaddr_t)pcie_cap_header >> 20;
-				continue;
-			}
-
-			/*
-			 * Found the serial number register!
-			 */
-
-			rc = pci_device_cfg_read_u32(dev,
-						     &dword_low, offset + 4);
-			rc = pci_device_cfg_read_u32(dev,
-						     &dword_high, offset + 8);
-			snprintf(hba_info->SerialNumber,
-				 sizeof(hba_info->SerialNumber),
-				"%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x\n",
-				dword_low & 0xff, (dword_low >> 8) & 0xff,
-				(dword_low >> 16) & 0xff, dword_low >> 24,
-				dword_high & 0xff, (dword_high >> 8) & 0xff,
-				(dword_high >> 16) & 0xff, dword_high >> 24);
-			break;
-		} while (offset);
-		break;
-	}
-}
-
-static void
-get_pci_device_info(struct pci_device *dev, struct hba_info *hba_info)
-{
-	const char *name;
-	u_int16_t class;
-	u_int8_t revision;
-	u_int8_t hdr_type;
-	char *unknown = "Unknown";
-
-	hba_info->vendor_id = dev->vendor_id;
-	hba_info->device_id = dev->device_id;
-	hba_info->subsystem_vendor_id = dev->subvendor_id;
-	hba_info->subsystem_device_id = dev->subdevice_id;
-
-	name = pci_device_get_vendor_name(dev);
-	if (!name)
-		name = unknown;
-	sa_strncpy_safe(hba_info->Manufacturer,
-			sizeof(hba_info->Manufacturer),
-			name, sizeof(hba_info->Manufacturer));
-
-	name = pci_device_get_device_name(dev);
-	if (!name)
-		name = unknown;
-	sa_strncpy_safe(hba_info->ModelDescription,
-			sizeof(hba_info->ModelDescription),
-			name, sizeof(hba_info->ModelDescription));
-
-	/*
-	 * Reading device class and revision from PCIe
-	 * configuration header space.
-	 */
-	pci_device_cfg_read_u16(dev, &class, PCI_CLASS_DEVICE);
-	hba_info->device_class = class;
-
-	pci_device_cfg_read_u8(dev, &revision, PCI_REVISION_ID);
-	snprintf(hba_info->HardwareVersion,
-		 sizeof(hba_info->HardwareVersion),
-		 "%02x", revision);
-
-	/*
-	 * Determine if the HBA is a single-function
-	 * or multi-function adapter.
-	 */
-	pci_device_cfg_read_u8(dev, &hdr_type, PCI_HEADER_TYPE);
-	if (hdr_type == 0x80)
-		hba_info->NumberOfPorts = 2;
-	else
-		hba_info->NumberOfPorts = 1;
-
-	/*
-	 * Searching for serial number in PCIe extended
-	 * capabilities space
-	 */
-	get_device_serial_number(dev, hba_info);
-}
-
-HBA_STATUS
-find_pci_device(struct hba_info *hba_info)
-{
-	struct pci_device_iterator *iterator;
-	struct pci_device *dev;
-	struct pci_slot_match match;
-
-	int rc;
-
-	rc = pci_system_init();
-	if (rc) {
-		fprintf(stderr, "pci_system_init failed\n");
-		return HBA_STATUS_ERROR;
-	}
-
-	match.domain = hba_info->domain;
-	match.bus = hba_info->bus;
-	match.dev = hba_info->dev;
-	match.func = hba_info->func;
-
-	iterator = pci_slot_match_iterator_create(&match);
-
-	for (;;) {
-		dev = pci_device_next(iterator);
-		if (!dev)
-			break;
-		get_pci_device_info(dev, hba_info);
-	}
-
-	pci_system_cleanup();
-	return HBA_STATUS_OK;
-}
-
diff --git a/libhbalinux/rport.c b/libhbalinux/rport.c
deleted file mode 100644
index 7b72872..0000000
--- a/libhbalinux/rport.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright (c) 2008, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU Lesser General Public License,
- * version 2.1, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include "utils.h"
-#include "api_lib.h"
-#include "adapt_impl.h"
-
-static int sys_read_port_state(const char *, const char *, u_int32_t *);
-static int sys_read_classes(const char *, const char *, u_int32_t *);
-
-static struct sa_table rports_table;          /* table of discovered ports */
-
-/*
- * Handle a single remote port from the /sys directory entry.
- * The return value is 0 unless an error is detected which should stop the
- * directory read.
- */
-static int
-sysfs_get_rport(struct dirent *dp, void *arg)
-{
-	struct port_info *rp;
-	HBA_PORTATTRIBUTES *rpa;
-	int rc;
-	u_int32_t hba;
-	u_int32_t port;
-	u_int32_t rp_index;
-	char *rport_dir;
-	char buf[256];
-
-	/*
-	 * Parse name into bus number, channel number, and remote port number.
-	 */
-	hba = ~0;
-	port = ~0;
-	rp_index = ~0;
-	rc = sscanf(dp->d_name, SYSFS_RPORT_DIR, &hba, &port, &rp_index);
-	if (rc != 3) {
-		fprintf(stderr,
-			"%s: remote port %s didn't parse."
-			" rc %d h 0x%x p 0x%x rp 0x%x\n", __func__,
-			dp->d_name, rc, hba, port, rp_index);
-		return 0;
-	}
-
-	/*
-	 * Allocate a remote port.
-	 */
-	rp = malloc(sizeof(*rp));
-	if (rp == NULL) {
-		fprintf(stderr, "%s: malloc for remote port %s failed,"
-			" errno=0x%x\n", __func__, dp->d_name, errno);
-		return ENOMEM;
-	}
-	memset(rp, 0, sizeof(*rp));
-	rp->ap_kern_hba = hba;
-	rp->ap_index = port;
-	rp->ap_disc_index = rp_index;
-	rpa = &rp->ap_attr;
-
-	snprintf(rpa->OSDeviceName, sizeof(rpa->OSDeviceName), "%s/%s",
-		SYSFS_RPORT_ROOT, dp->d_name);
-	rport_dir = rpa->OSDeviceName;
-	rc = 0;
-	rc |= sys_read_wwn(rport_dir, "node_name", &rpa->NodeWWN);
-	rc |= sys_read_wwn(rport_dir, "port_name", &rpa->PortWWN);
-	rc |= sa_sys_read_u32(rport_dir, "port_id", &rpa->PortFcId);
-	rc |= sa_sys_read_u32(rport_dir, "scsi_target_id", &rp->ap_scsi_target);
-	rc |= sa_sys_read_line(rport_dir, "maxframe_size", buf, sizeof(buf));
-	sscanf(buf, "%d", &rpa->PortMaxFrameSize);
-	rc |= sys_read_port_state(rport_dir, "port_state", &rpa->PortState);
-	rc |= sys_read_classes(rport_dir, "supported_classes",
-				   &rpa->PortSupportedClassofService);
-	if (rc != 0 || sa_table_append(&rports_table, rp) < 0) {
-		if (rc != 0)
-			fprintf(stderr,
-				"%s: errors (%x) from /sys reads in %s\n",
-				__func__, rc, dp->d_name);
-		else
-			fprintf(stderr,
-				"%s: sa_table_append error on rport %s\n",
-				__func__, dp->d_name);
-		free(rp);
-	}
-	return 0;
-}
-
-/*
- * Get remote port information from /sys.
- */
-static void
-sysfs_find_rports(void)
-{
-	sa_dir_read(SYSFS_RPORT_ROOT, sysfs_get_rport, NULL);
-}
-
-/*
- * Read port state as formatted by scsi_transport_fc.c in the linux kernel.
- */
-static int
-sys_read_port_state(const char *dir, const char *file, u_int32_t *statep)
-{
-	char buf[256];
-	int rc;
-
-	rc = sa_sys_read_line(dir, file, buf, sizeof(buf));
-	if (rc == 0) {
-		rc = sa_enum_encode(port_states_table, buf, statep);
-		if (rc != 0)
-			fprintf(stderr,
-				"%s: parse error. file %s/%s line '%s'\n",
-				__func__, dir, file, buf);
-	}
-	return rc;
-}
-
-/*
- * Read class list as formatted by scsi_transport_fc.c in the linux kernel.
- * Format is expected to be "Class 3[, Class 4]..."
- * Actually accepts "[Class ]3[,[ ][Class ]4]..." (i.e., "Class" and spaces
- * are optional).
- */
-static int
-sys_read_classes(const char *dir, const char *file, u_int32_t *classp)
-{
-	char buf[256];
-	int rc;
-	u_int32_t val;
-	char *cp;
-	char *ep;
-
-	*classp = 0;
-	rc = sa_sys_read_line(dir, file, buf, sizeof(buf));
-	if (rc == 0 && strstr(buf, "unspecified") == NULL) {
-		for (cp = buf; *cp != '\0'; cp = ep) {
-			if (strncmp(cp, "Class ", 6) == 0)
-				cp += 6;
-			val = strtoul(cp, &ep, 10);
-			*classp |= 1 << val;
-			if (*ep == '\0')
-				break;
-			if (*ep == ',') {
-				ep++;
-				if (*ep == ' ')
-					ep++;
-			} else {
-				fprintf(stderr, "%s: parse error. file %s/%s "
-				       "line '%s' ep '%c'\n", __func__,
-					dir, file, buf, *ep);
-				rc = -1;
-				break;
-			}
-		}
-	}
-	return rc;
-}
-
-/*
- * Get all discovered ports for a particular port using /sys.
- */
-void
-get_rport_info(struct port_info *pp)
-{
-	struct port_info *rp;
-	int rp_count = 0;
-	int ri;
-
-	if (rports_table.st_size == 0)
-		sysfs_find_rports();
-
-	for (ri = 0; ri < rports_table.st_size; ri++) {
-		rp = sa_table_lookup(&rports_table, ri);
-		if (rp != NULL) {
-			if (rp->ap_kern_hba == pp->ap_kern_hba &&
-			    rp->ap_index == pp->ap_index &&
-			    rp->ap_adapt == NULL) {
-				rp->ap_adapt = pp->ap_adapt;
-				if (sa_table_lookup(&pp->ap_rports,
-						    rp->ap_disc_index)) {
-					fprintf(stderr,
-						"%s: discovered port exists. "
-					       "hba %x port %x rport %x\n",
-					       __func__, pp->ap_kern_hba,
-					       pp->ap_index, rp->ap_disc_index);
-				}
-				sa_table_insert(&pp->ap_rports,
-						rp->ap_disc_index, rp);
-			}
-			rp_count++;
-		}
-	}
-}
-
diff --git a/libhbalinux/scsi.c b/libhbalinux/scsi.c
deleted file mode 100644
index c04d410..0000000
--- a/libhbalinux/scsi.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (c) 2008, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU Lesser General Public License,
- * version 2.1, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include "utils.h"
-#include "api_lib.h"
-#include "adapt_impl.h"
-#include "bind_impl.h"
-#include "fc_scsi.h"
-
-/*
- * Inquiry V1.
- */
-HBA_STATUS
-scsi_inquiry_v1(HBA_HANDLE handle, HBA_WWN disc_wwpn, HBA_UINT64 fc_lun,
-		    HBA_UINT8 evpd, HBA_UINT32 page_code, void *resp,
-		    HBA_UINT32 resp_len, void *sense, HBA_UINT32 sense_len)
-{
-	struct port_info *pp;
-	char sg_name[50];
-	HBA_UINT8 stat;
-	HBA_STATUS status;
-
-	/*
-	 * Find port.
-	 */
-	pp = adapter_get_port(handle, 0);
-	if (pp == NULL)
-		return HBA_STATUS_ERROR_INVALID_HANDLE;
-
-	if (get_binding_sg_name(
-	    pp, disc_wwpn, fc_lun, sg_name, sizeof(sg_name)) != 0)
-		return HBA_STATUS_ERROR_TARGET_LUN;
-
-	status = sg_issue_inquiry(sg_name, evpd ? SCSI_INQF_EVPD : 0, page_code,
-				resp, &resp_len, &stat, sense, &sense_len);
-	if (status == HBA_STATUS_OK && stat == SCSI_ST_CHECK)
-		status = HBA_STATUS_SCSI_CHECK_CONDITION;
-
-	return status;
-}
-
-/*
- * Inquiry V2.
- */
-HBA_STATUS
-scsi_inquiry_v2(HBA_HANDLE handle, HBA_WWN wwpn, HBA_WWN disc_wwpn,
-		    HBA_UINT64 fc_lun, HBA_UINT8 cdb_byte1,
-		    HBA_UINT8 cdb_byte2, void *resp, HBA_UINT32 *resp_lenp,
-		    HBA_UINT8 *statp, void *sense, HBA_UINT32 *sense_lenp)
-{
-	struct port_info *pp;
-	char sg_name[50];
-
-	/*
-	 * Find port.
-	 */
-	pp = adapter_get_port_by_wwn(handle, wwpn, NULL);
-	if (pp == NULL)
-		return HBA_STATUS_ERROR_ILLEGAL_WWN;
-
-	if (get_binding_sg_name(
-	    pp, disc_wwpn, fc_lun, sg_name, sizeof(sg_name)) != 0)
-		return HBA_STATUS_ERROR_TARGET_LUN;
-
-	return sg_issue_inquiry(sg_name, cdb_byte1, cdb_byte2,
-			       resp, resp_lenp, statp, sense, sense_lenp);
-}
-
-/*
- * Read capacity V1.
- */
-HBA_STATUS
-scsi_read_capacity_v1(HBA_HANDLE handle, HBA_WWN disc_wwpn,
-			  HBA_UINT64 fc_lun, void *resp,
-			  HBA_UINT32 resp_len, void *sense,
-			  HBA_UINT32 sense_len)
-{
-	struct port_info *pp;
-	char sg_name[50];
-	HBA_UINT8 stat;
-	HBA_STATUS status;
-
-	/*
-	 * Find port.
-	 */
-	pp = adapter_get_port(handle, 0);
-	if (pp == NULL)
-		return HBA_STATUS_ERROR_INVALID_HANDLE;
-
-	if (get_binding_sg_name(
-	    pp, disc_wwpn, fc_lun, sg_name, sizeof(sg_name)) != 0)
-		return HBA_STATUS_ERROR_TARGET_LUN;
-
-	status = sg_issue_read_capacity(sg_name, resp, &resp_len,
-				 &stat, sense, &sense_len);
-	if (status == HBA_STATUS_OK && stat == SCSI_ST_CHECK)
-		status = HBA_STATUS_SCSI_CHECK_CONDITION;
-
-	return status;
-}
-
-/*
- * Read capacity V2.
- */
-HBA_STATUS
-scsi_read_capacity_v2(HBA_HANDLE handle, HBA_WWN wwpn,
-			  HBA_WWN disc_wwpn, HBA_UINT64 fc_lun,
-			  void *resp, HBA_UINT32 *resp_lenp,
-			  HBA_UINT8 *statp, void *sense,
-			  HBA_UINT32 *sense_lenp)
-{
-	struct port_info *pp;
-	char sg_name[50];
-
-	/*
-	 * Find port.
-	 */
-	pp = adapter_get_port_by_wwn(handle, wwpn, NULL);
-	if (pp == NULL)
-		return HBA_STATUS_ERROR_ILLEGAL_WWN;
-
-	if (get_binding_sg_name(
-	    pp, disc_wwpn, fc_lun, sg_name, sizeof(sg_name)) != 0)
-		return HBA_STATUS_ERROR_TARGET_LUN;
-
-	return sg_issue_read_capacity(sg_name, resp, resp_lenp,
-				statp, sense, sense_lenp);
-}
-
-/*
- * Report LUNS V1.
- */
-HBA_STATUS
-scsi_report_luns_v1(HBA_HANDLE handle, HBA_WWN disc_wwpn,
-			void *resp, HBA_UINT32 resp_len,
-			void *sense, HBA_UINT32 sense_len)
-{
-	struct port_info *pp;
-	char sg_name[50];
-	HBA_UINT8 stat;
-	HBA_STATUS status;
-
-	/*
-	 * Find port.
-	 */
-	pp = adapter_get_port(handle, 0);
-	if (pp == NULL)
-		return HBA_STATUS_ERROR_INVALID_HANDLE;
-
-	if (get_binding_sg_name(
-	    pp, disc_wwpn, 0, sg_name, sizeof(sg_name)) != 0)
-		return HBA_STATUS_ERROR_TARGET_PORT_WWN;
-
-	status = sg_issue_report_luns(sg_name, resp, &resp_len,
-				    &stat, sense, &sense_len);
-	if (status == HBA_STATUS_OK && stat == SCSI_ST_CHECK)
-		status = HBA_STATUS_SCSI_CHECK_CONDITION;
-
-	return status;
-}
-
-/*
- * Report LUNS V2.
- */
-HBA_STATUS
-scsi_report_luns_v2(HBA_HANDLE handle, HBA_WWN wwpn,
-			HBA_WWN disc_wwpn, void *resp,
-			HBA_UINT32 *resp_lenp, HBA_UINT8 *statp,
-			void *sense, HBA_UINT32 *sense_lenp)
-{
-	struct port_info *pp;
-	char sg_name[50];
-
-	/*
-	 * Find port.
-	 */
-	pp = adapter_get_port_by_wwn(handle, wwpn, NULL);
-	if (pp == NULL)
-		return HBA_STATUS_ERROR_ILLEGAL_WWN;
-
-	if (get_binding_sg_name(
-	    pp, disc_wwpn, 0, sg_name, sizeof(sg_name)) != 0)
-		return HBA_STATUS_ERROR_TARGET_PORT_WWN;
-
-	return sg_issue_report_luns(sg_name, resp, resp_lenp,
-				  statp, sense, sense_lenp);
-}
-
diff --git a/libhbalinux/sg.c b/libhbalinux/sg.c
deleted file mode 100644
index f324b9a..0000000
--- a/libhbalinux/sg.c
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Copyright (c) 2008, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU Lesser General Public License,
- * version 2.1, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <sys/ioctl.h>
-#include "utils.h"
-#include "api_lib.h"
-#include "adapt_impl.h"
-#include "fc_scsi.h"
-
-/*
- * Perform INQUIRY of SCSI-generic device.
- */
-HBA_STATUS
-sg_issue_inquiry(const char *file, HBA_UINT8 cdb_byte1,
-	       HBA_UINT8 cdb_byte2, void *buf, HBA_UINT32 *lenp,
-	       HBA_UINT8 *statp, void *sense, HBA_UINT32 *sense_lenp)
-{
-	struct sg_io_hdr hdr;
-	struct scsi_inquiry cmd;
-	size_t len;
-	HBA_UINT32 slen;
-	int fd;
-	int rc;
-
-	len = *lenp;
-	slen = *sense_lenp;
-	if (slen > 255)
-		slen = 255;   /* must fit in an 8-bit field */
-	if (len > 255)
-		len = 255;    /* sometimes must fit in 8-byte field */
-	*lenp = 0;
-	*statp = 0;
-	fd = open(file, O_RDWR);
-	if (fd < 0) {
-		fprintf(stderr, "%s: open of %s failed, errno=0x%x\n",
-			__func__, file, errno);
-		return HBA_STATUS_ERROR;
-	}
-	memset(&hdr, 0, sizeof(hdr));
-	memset(&cmd, 0, sizeof(cmd));
-	memset(buf, 0, len);
-
-	cmd.in_op = SCSI_OP_INQUIRY;
-	cmd.in_flags = cdb_byte1;
-	cmd.in_page_code = cdb_byte2;
-	ua_net16_put(&cmd.in_alloc_len, len); /* field may actually be 8 bits */
-
-	hdr.interface_id = 'S';
-	hdr.dxfer_direction = SG_DXFER_FROM_DEV;
-	hdr.cmd_len = sizeof(cmd);
-	hdr.mx_sb_len = slen;
-	hdr.dxfer_len = len;
-	hdr.dxferp = (unsigned char *) buf;
-	hdr.cmdp = (unsigned char *) &cmd;
-	hdr.sbp = (unsigned char *) sense;
-	hdr.timeout = 3000;                     /* mS to wait for result */
-
-	rc = ioctl(fd, SG_IO, &hdr);
-	if (rc < 0) {
-		rc = errno;
-		fprintf(stderr, "%s: SG_IO error. file %s, errno=0x%x\n",
-			__func__, file, errno);
-		return HBA_STATUS_ERROR;
-	}
-	close(fd);
-	*lenp = len - hdr.resid;
-	*sense_lenp = hdr.sb_len_wr;
-	*statp = hdr.status;
-	return HBA_STATUS_OK;
-}
-
-static inline unsigned int
-sg_get_id_type(struct scsi_inquiry_desc *dp)
-{
-	return dp->id_type_flags & SCSI_INQT_TYPE_MASK;
-}
-
-/*
- * Get device ID information for HBA-API.
- * See the spec.  We get the "best" information and leave the rest.
- * The buffer is left empty if nothing is gotten.
- */
-void
-sg_get_dev_id(const char *name, char *buf, size_t result_len)
-{
-	struct scsi_inquiry_dev_id *idp;
-	struct scsi_inquiry_desc *dp;
-	struct scsi_inquiry_desc *best = NULL;
-	char sense[252];
-	HBA_UINT32 len;
-	HBA_UINT32 slen;
-	u_char scsi_stat;
-	size_t rlen;
-	size_t dlen;
-	unsigned int type;
-
-	memset(buf, 0, result_len);
-	len = result_len;
-	slen = sizeof(sense);
-	idp = (struct scsi_inquiry_dev_id *) buf;
-	sg_issue_inquiry(name, SCSI_INQF_EVPD, SCSI_INQP_DEV_ID,
-			buf, &len, &scsi_stat, sense, &slen);
-	if (len < sizeof(*idp))
-		return;
-	if (idp->is_page_code != SCSI_INQP_DEV_ID)
-		return;
-	len -= sizeof(*idp);
-	rlen = net16_get(&idp->is_page_len);
-	if (rlen > len)
-		rlen = len;
-	dp = (struct scsi_inquiry_desc *) (idp + 1);
-	for (; rlen >= sizeof(*dp);
-	     rlen -= dlen,
-	     dp = (struct scsi_inquiry_desc *) ((char *) dp + dlen)) {
-		dlen = dp->id_designator_len + sizeof(*dp) -
-		       sizeof(dp->id_designator[0]);
-		if (dlen > rlen)
-			break;
-		type = sg_get_id_type(dp);
-		if (type > SCSI_DTYPE_NAA)
-			continue;
-		if (best == NULL)
-			best = dp;
-		else if (type == sg_get_id_type(best) &&
-			   (dp->id_designator_len < best->id_designator_len ||
-			   (dp->id_designator_len == best->id_designator_len &&
-			   memcmp(dp->id_designator, best->id_designator,
-			   best->id_designator_len) < 0))) {
-			best = dp;
-		} else if (type > sg_get_id_type(best))
-			best = dp;
-	}
-	if (best) {
-		dp = best;
-		dlen = dp->id_designator_len + sizeof(*dp) -
-			sizeof(dp->id_designator[0]);
-		if (dlen > result_len)
-			dlen = 0;                       /* can't happen */
-		else
-			memmove(buf, dp, dlen);         /* areas may overlap */
-		memset(buf +  dlen, 0, result_len - dlen);
-	}
-}
-
-/*
- * Read Capacity for HBA-API.
- */
-HBA_STATUS
-sg_issue_read_capacity(const char *file, void *resp, HBA_UINT32 *resp_lenp,
-		HBA_UINT8 *statp, void *sense, HBA_UINT32 *sense_lenp)
-{
-	struct sg_io_hdr hdr;
-	struct scsi_rcap10 cmd;
-	size_t len;
-	int fd;
-	int rc;
-
-	len = *resp_lenp;
-	*resp_lenp = 0;
-	fd = open(file, O_RDWR);
-	if (fd < 0) {
-		fprintf(stderr, "%s: open of %s failed, errno=0x%x\n",
-			__func__, file, errno);
-		return errno;
-	}
-	memset(&hdr, 0, sizeof(hdr));
-	memset(&cmd, 0, sizeof(cmd));
-
-	cmd.rc_op = SCSI_OP_READ_CAP10;
-
-	hdr.interface_id = 'S';
-	hdr.dxfer_direction = SG_DXFER_FROM_DEV;
-	hdr.cmd_len = sizeof(cmd);
-	hdr.mx_sb_len = *sense_lenp;
-	hdr.dxfer_len = len;
-	hdr.dxferp = (unsigned char *) resp;
-	hdr.cmdp = (unsigned char *) &cmd;
-	hdr.sbp = (unsigned char *) sense;
-	hdr.timeout = UINT_MAX;
-	hdr.timeout = 3000;                     /* mS to wait for result */
-
-	rc = ioctl(fd, SG_IO, &hdr);
-	if (rc < 0) {
-		rc = errno;
-		fprintf(stderr, "%s: SG_IO error. file %s, errno=0x%x\n",
-			__func__, file, errno);
-		return HBA_STATUS_ERROR;
-	}
-	close(fd);
-	*resp_lenp = len - hdr.resid;
-	*sense_lenp = hdr.sb_len_wr;
-	*statp = hdr.status;
-	return HBA_STATUS_OK;
-}
-
-/*
- * Report LUNs for HBA-API.
- */
-HBA_STATUS
-sg_issue_report_luns(const char *file, void *resp, HBA_UINT32 *resp_lenp,
-		   HBA_UINT8 *statp, void *sense, HBA_UINT32 *sense_lenp)
-{
-	struct sg_io_hdr hdr;
-	struct scsi_report_luns cmd;
-	size_t len;
-	int fd;
-	int rc;
-
-	len = *resp_lenp;
-	*resp_lenp = 0;
-	fd = open(file, O_RDWR);
-	if (fd < 0) {
-		fprintf(stderr, "%s: open of %s failed, errno=0x%x\n",
-			__func__, file, errno);
-		return errno;
-	}
-	memset(&hdr, 0, sizeof(hdr));
-	memset(&cmd, 0, sizeof(cmd));
-
-	cmd.rl_op = SCSI_OP_REPORT_LUNS;
-	ua_net32_put(&cmd.rl_alloc_len, len);
-
-	hdr.interface_id = 'S';
-	hdr.dxfer_direction = SG_DXFER_FROM_DEV;
-	hdr.cmd_len = sizeof(cmd);
-	hdr.mx_sb_len = *sense_lenp;
-	hdr.dxfer_len = len;
-	hdr.dxferp = (unsigned char *) resp;
-	hdr.cmdp = (unsigned char *) &cmd;
-	hdr.sbp = (unsigned char *) sense;
-	hdr.timeout = UINT_MAX;
-	hdr.timeout = 3000;                     /* mS to wait for result */
-
-	rc = ioctl(fd, SG_IO, &hdr);
-	if (rc < 0) {
-		rc = errno;
-		fprintf(stderr, "%s: SG_IO error. file %s, errno=0x%x\n",
-			__func__, file, errno);
-		return HBA_STATUS_ERROR;
-	}
-	close(fd);
-	*resp_lenp = len - hdr.resid;
-	*sense_lenp = hdr.sb_len_wr;
-	*statp = hdr.status;
-	return HBA_STATUS_OK;
-}
-
diff --git a/libhbalinux/utils.c b/libhbalinux/utils.c
deleted file mode 100644
index cc5c655..0000000
--- a/libhbalinux/utils.c
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * Copyright (c) 2008, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU Lesser General Public License,
- * version 2.1, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include "utils.h"
-
-/*
- * Read a line from the specified file in the specified directory
- * into the buffer.  The file is opened and closed.
- * Any trailing white space is trimmed off.
- * This is useful for accessing /sys files.
- * Returns 0 or an error number.
- */
-int
-sa_sys_read_line(const char *dir, const char *file, char *buf, size_t len)
-{
-	FILE *fp;
-	char file_name[256];
-	char *cp;
-	int rc = 0;
-
-	snprintf(file_name, sizeof(file_name), "%s/%s", dir, file);
-	fp = fopen(file_name, "r");
-	if (fp == NULL)
-		rc = -1;
-	else {
-		cp = fgets(buf, len, fp);
-		if (cp == NULL) {
-			fprintf(stderr,
-				"%s: read error or empty file %s,"
-				" errno=0x%x\n", __func__,
-				file_name, errno);
-			rc = -1;
-		} else {
-
-			/*
-			 * Trim off trailing newline or other white space.
-			 */
-			cp = buf + strlen(buf);
-			while (--cp >= buf && isspace(*cp))
-				*cp = '\0';
-		}
-		fclose(fp);
-	}
-	return rc;
-}
-
-/*
- * Write a string to the specified file in the specified directory.
- * The file is opened and closed.
- * The string has a new-line appended to it.
- * This is useful for accessing /sys files.
- * Returns 0 or an error number.
- */
-int
-sa_sys_write_line(const char *dir, const char *file, const char *string)
-{
-	FILE *fp;
-	char file_name[256];
-	int rc = 0;
-
-	snprintf(file_name, sizeof(file_name), "%s/%s", dir, file);
-	fp = fopen(file_name, "w");
-	if (fp == NULL) {
-		fprintf(stderr, "%s: fopen of %s failed, errno=0x%x\n",
-			__func__, file_name, errno);
-		rc = -1;
-	} else {
-		rc = fprintf(fp, "%s\n", string);
-		if (rc < 0)
-			fprintf(stderr,
-				"%s: write to %s of %s failed, errno=0x%x\n",
-				__func__, file_name, string, errno);
-		fclose(fp);
-	}
-	return rc;
-}
-
-int
-sa_sys_read_u32(const char *dir, const char *file, u_int32_t *vp)
-{
-	char buf[256];
-	int rc;
-	u_int32_t val;
-	char *endptr;
-
-	rc = sa_sys_read_line(dir, file, buf, sizeof(buf));
-	if (rc == 0) {
-		val = strtoul(buf, &endptr, 0);
-		if (*endptr != '\0') {
-			fprintf(stderr,
-				"%s: parse error. file %s/%s line '%s'\n",
-				__func__, dir, file, buf);
-			rc = -1;
-		} else
-			*vp = val;
-	}
-	return rc;
-}
-
-int
-sa_sys_read_u64(const char *dir, const char *file, u_int64_t *vp)
-{
-	char buf[256];
-	int rc;
-	u_int64_t val;
-	char *endptr;
-
-	rc = sa_sys_read_line(dir, file, buf, sizeof(buf));
-	if (rc == 0) {
-		val = strtoull(buf, &endptr, 0);
-		if (*endptr != '\0') {
-			fprintf(stderr,
-				"%s: parse error. file %s/%s line '%s'\n",
-				__func__, dir, file, buf);
-			rc = -1;
-		} else
-			*vp = val;
-	}
-	return rc;
-}
-
-/*
- * Make a printable NUL-terminated copy of the string.
- * The source buffer might not be NUL-terminated.
- */
-char *
-sa_strncpy_safe(char *dest, size_t len, const char *src, size_t src_len)
-{
-	char *dp = dest;
-	const char *sp = src;
-
-	while (len-- > 1 && src_len-- > 0 && *sp != '\0') {
-		*dp++ = isprint(*sp) ? *sp : (isspace(*sp) ? ' ' : '.');
-		sp++;
-	}
-	*dp = '\0';
-
-	/*
-	 * Take off trailing blanks.
-	 */
-	while (--dp >= dest && isspace(*dp))
-		*dp = '\0';
-
-	return dest;
-}
-
-/** sa_enum_encode(tp, name, valp)
- *
- * @param tp pointer to table of names and values, struct sa_nameval.
- * @param name string to be encoded into a value
- * @returns zero on success, non-zero if no matching string found.
- */
-int
-sa_enum_encode(const struct sa_nameval *tp, const char *name, u_int32_t *valp)
-{
-	for (; tp->nv_name != NULL; tp++) {
-		if (strcasecmp(tp->nv_name, name) == 0) {
-			*valp = tp->nv_val;
-			return 0;
-		}
-	}
-	return -1;
-}
-
-/** sa_enum_decode(buf, len, tp, val)
- *
- * @param buf buffer for result (may be used or not).
- * @param len size of buffer (at least 32 bytes recommended).
- * @param tp pointer to table of names and values, struct sa_nameval.
- * @param val value to be decoded into a name.
- * @returns pointer to name string.  Unknown values are put into buffer in hex.
- */
-const char *
-sa_enum_decode(char *buf, size_t len,
-		const struct sa_nameval *tp, u_int32_t val)
-{
-	for (; tp->nv_name != NULL; tp++) {
-		if (tp->nv_val == val)
-			return tp->nv_name;
-	}
-	snprintf(buf, len, "Unknown (code 0x%X)", val);
-	return buf;
-}
-
-/*
- * Read through a directory and call a function for each entry.
- */
-int
-sa_dir_read(char *dir_name, int (*func)(struct dirent *dp, void *), void *arg)
-{
-	DIR *dir;
-	struct dirent *dp;
-	int error = 0;
-
-	dir = opendir(dir_name);
-	if (dir == NULL)
-		error = errno;
-	else {
-		while ((dp = readdir(dir)) != NULL && error == 0) {
-			if (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' ||
-			   (dp->d_name[1] == '.' && dp->d_name[2] == '\0')))
-				continue;
-			error = (*func)(dp, arg);
-		}
-		closedir(dir);
-	}
-	return error;
-}
-
-/*
- * Size of on-stack line buffers.
- * These shouldn't be to large for a kernel stack frame.
- */
-#define SA_LOG_BUF_LEN  200	/* on-stack line buffer size */
-
-static const u_int32_t sa_table_growth = 16;        /* entries to grow by */
-
-/** sa_table_grow(tp, index) - add space to a table for index.
- *
- * @param tp pointer to sa_table structure.
- * @param index - new index past the end of the current table.
- * @returns new index, or -1 if table couldn't be grown.
- *
- * Note: if the table has never been used, and is still all zero, this works.
- *
- * Note: perhaps not safe for multithreading.  Caller can lock the table
- * externally, but reallocation can take a while, during which time the
- * caller may not wish to hold the lock.
- */
-int
-sa_table_grow(struct sa_table *tp, u_int32_t index)
-{
-	u_int32_t new_size;
-	void **ap;
-
-	if (index >= tp->st_size) {
-		new_size = index + sa_table_growth;
-		ap = realloc(tp->st_table, new_size * sizeof(*ap));
-		if (ap == NULL)
-			return -1;
-		memset(ap + tp->st_size, 0,
-			(new_size - tp->st_size) * sizeof(*ap));
-		tp->st_table = ap;
-		tp->st_size = new_size;
-	}
-	tp->st_limit = index + 1;
-	return index;
-}
-
-/** sa_table_destroy(tp) - free memory used by table.
- *
- * @param tp pointer to sa_table structure.
- */
-void
-sa_table_destroy(struct sa_table *tp)
-{
-	if (tp->st_table) {
-		free(tp->st_table);
-		tp->st_table = NULL;
-	}
-	tp->st_limit = 0;
-	tp->st_size = 0;
-}
-
-/** sa_table_destroy_all(tp) - free memory used by table, including entries.
- *
- * @param tp pointer to sa_table structure.
- */
-void
-sa_table_destroy_all(struct sa_table *tp)
-{
-	int  i;
-
-	if (tp->st_table) {
-		for (i = 0; i < tp->st_limit; i++) {
-			if (tp->st_table[i]) {
-				free(tp->st_table[i]);
-				tp->st_table[i] = NULL;
-			}
-		}
-	}
-	sa_table_destroy(tp);
-}
-
-/** sa_table_iterate(tp, handler, arg)
- *
- * @param tp pointer to sa_table structure.
- * @param handler function to be called for each non-NULL entry.
- * @param arg argument for function.
- */
-void
-sa_table_iterate(struct sa_table *tp,
-		 void (*handler)(void *ep, void *arg),
-		 void *arg)
-{
-	int i;
-	void *ep;
-
-	for (i = 0; i < tp->st_limit; i++) {
-		ep = tp->st_table[i];
-		if (ep != NULL)
-			(*handler)(ep, arg);
-	}
-}
-
-/** sa_table_search(tp, match, arg)
- *
- * @param tp pointer to sa_table structure.
- * @param match function to compare entries with arg and
- *	 return non-NULL if match.
- * @param arg argument for match function.
- *
- * Note that the value found could actually be something not in the table
- * if the match function is doing something clever, like returning a
- * sub-structure of the table entry.
- */
-void *
-sa_table_search(struct sa_table *tp, void *(*match)(void *ep, void *arg),
-	void *arg)
-{
-	int i;
-	void *found = NULL;
-	void *ep;
-
-	for (i = 0; i < tp->st_limit; i++) {
-		ep = tp->st_table[i];
-		found = (*match)(ep, arg);
-		if (ep != NULL && found != NULL)
-			break;
-	}
-	return found;
-}
diff --git a/libhbalinux/utils.h b/libhbalinux/utils.h
deleted file mode 100644
index 9228c26..0000000
--- a/libhbalinux/utils.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (c) 2008, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU Lesser General Public License,
- * version 2.1, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#ifndef _UTILS_H_
-#define _UTILS_H_
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/param.h>
-#include <linux/types.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <errno.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <string.h>
-#include <time.h>
-#include <fcntl.h>
-#include <malloc.h>
-#include <pthread.h>
-#include <limits.h>
-#include <scsi/sg.h>
-#include "hbaapi.h"
-#include "vendorhbaapi.h"
-#include "fc_types.h"
-
-/*
- * Structure for tables encoding and decoding name-value pairs such as enums.
- */
-struct sa_nameval {
-	char        *nv_name;
-	u_int32_t   nv_val;
-};
-
-/*
- * Structure for integer-indexed tables that can grow.
- */
-struct sa_table {
-	u_int32_t   st_size;        /* number of entries in table */
-	u_int32_t   st_limit;       /* end of valid entries in table (public) */
-	void        **st_table;     /* re-allocatable array of pointers */
-};
-
-/*
- * Function prototypes
- */
-extern int sa_sys_read_line(const char *, const char *, char *, size_t);
-extern int sa_sys_write_line(const char *, const char *, const char *);
-extern int sa_sys_read_u32(const char *, const char *, u_int32_t *);
-extern int sa_sys_read_u64(const char *, const char *, u_int64_t *);
-extern int sa_dir_read(char *, int (*)(struct dirent *, void *), void *);
-extern char *sa_strncpy_safe(char *dest, size_t len,
-			     const char *src, size_t src_len);
-extern const char *sa_enum_decode(char *, size_t,
-				  const struct sa_nameval *, u_int32_t);
-extern int sa_enum_encode(const struct sa_nameval *tp,
-			const char *, u_int32_t *);
-extern const char *sa_flags_decode(char *, size_t,
-				   const struct sa_nameval *, u_int32_t);
-extern int sa_table_grow(struct sa_table *, u_int32_t index);
-extern void sa_table_destroy_all(struct sa_table *);
-extern void sa_table_destroy(struct sa_table *);
-extern void sa_table_iterate(struct sa_table *tp,
-			void (*handler)(void *ep, void *arg), void *arg);
-extern void *sa_table_search(struct sa_table *tp,
-			void *(*match)(void *ep, void *arg), void *arg);
-
-/** sa_table_init(tp) - initialize a table.
- * @param tp table pointer.
- *
- * This just clears a table structure that was allocated by the caller.
- */
-static inline void sa_table_init(struct sa_table *tp)
-{
-	memset(tp, 0, sizeof(*tp));
-}
-
-/** sa_table_lookup(tp, index) - lookup an entry in the table.
- * @param tp table pointer.
- * @param index the index in the table to access
- * @returns the entry, or NULL if the index wasn't valid.
- */
-static inline void *sa_table_lookup(const struct sa_table *tp, u_int32_t index)
-{
-	void *ep = NULL;
-
-	if (index < tp->st_limit)
-		ep = tp->st_table[index];
-	return ep;
-}
-
-/** sa_table_lookup_n(tp, n) - find Nth non-empty entry in a table.
- * @param tp table pointer.
- * @param n is the entry number, the first non-empty entry is 0.
- * @returns the entry, or NULL if the end of the table reached first.
- */
-static inline void *sa_table_lookup_n(const struct sa_table *tp, u_int32_t n)
-{
-	void *ep = NULL;
-	u_int32_t   i;
-
-	for (i = 0; i < tp->st_limit; i++) {
-		ep = tp->st_table[i];
-		if (ep != NULL && n-- == 0)
-			return ep;
-	}
-	return NULL;
-}
-
-/** sa_table_insert(tp, index, ep) - Replace or insert an entry in the table.
- * @param tp table pointer.
- * @param index the index for the new entry.
- * @param ep entry pointer.
- * @returns index on success, or -1 if the insert failed.
- *
- * Note: if the table has never been used, and is still all zero, this works.
- *
- * Note: perhaps not safe for multithreading.  Caller can lock the table
- * externally, but reallocation can take a while, during which time the
- * caller may not wish to hold the lock.
- */
-static inline int sa_table_insert(struct sa_table *tp,
-				  u_int32_t index, void *ep)
-{
-	if (index >= tp->st_limit && sa_table_grow(tp, index) < 0)
-		return -1;
-	tp->st_table[index] = ep;
-	return index;
-}
-
-/** sa_table_append(tp, ep) - add entry to table and return index.
- *
- * @param tp pointer to sa_table structure.
- * @param ep pointer to new entry, to be added at the end of the table.
- * @returns new index, or -1 if table couldn't be grown.
- *
- * See notes on sa_table_insert().
- */
-static inline int
-sa_table_append(struct sa_table *tp, void *ep)
-{
-	return sa_table_insert(tp, tp->st_limit, ep);
-}
-
-/** sa_table_sort(tp, compare) - sort table in place
- *
- * @param tp pointer to sa_table structure.
- * @param compare function to compare two entries.  It is called with pointers
- * to the pointers to the entries to be compared.  See qsort(3).
- */
-static inline void
-sa_table_sort(struct sa_table *tp, int (*compare)(const void **, const void **))
-{
-	qsort(tp->st_table, tp->st_limit, sizeof(void *),
-		(int (*)(const void *, const void *)) compare);
-}
-
-#endif /* _UTILS_H_ */
diff --git a/src/Makefile b/src/Makefile
new file mode 100644
index 0000000..b4f19f5
--- /dev/null
+++ b/src/Makefile
@@ -0,0 +1,114 @@
+#
+# Makefile for libhbalinux/src
+#
+
+#
+# The target shared library to be built
+#
+LIB = libhbalinux.so
+
+#
+# List of legal build component names
+#
+LEGAL_ARCH = i386 i486 i586 i686 x86_64
+LEGAL_OS = linux Linux
+
+#
+# Default build directory
+#
+BUILD_DIR := .
+
+#
+# Commands used for build
+#
+CC = cc 
+RM = rm
+SED = sed
+INSTALL = install
+
+#
+#
+# Validating OS and the machine architecture.
+#
+ifneq "$(filter-out $(LEGAL_ARCH), $(shell uname -i))" ""
+    $(error bad build architecture $(shell uname -i))
+else
+ifneq "$(filter-out $(LEGAL_OS), $(shell uname -s))" ""
+    $(error bad build OS $(shell uname -s))
+else
+
+ifeq ($(shell uname -i),x86_64)
+    CFLAGS += -m64
+    .LIBPATTERNS = /usr/lib64/lib%.so /usr/lib64/lib%.a
+    INSTALL_DIR := /usr/local/lib64
+else
+    .LIBPATTERNS = /usr/lib/lib%.so \
+                   /usr/lib/lib%.a \
+                   /usr/local/lib/lib%.a \
+                   /usr/local/lib/lib%.so
+    INSTALL_DIR := /usr/local/lib
+endif
+
+LIBRARIES = -lrt -lpciaccess
+
+#
+# Set up the C compiler flags
+#
+#DATE=`date "+%D-%T"`
+DATE=`date "+%Y/%m/%d %T %Z"`
+CFLAGS += -DBUILD_DATE="\"${DATE}\""
+CFLAGS += -fPIC -O0 -g -Wall -Wall -Werror
+CFLAGS += -I.
+CFLAGS += -I../include
+CFLAGS += -I../hbaapi_src_2.2
+
+#
+# C files to be compiled
+#
+SOURCES += \
+	lib.c \
+	adapt.c \
+	lport.c \
+	rport.c \
+	bind.c \
+	pci.c \
+	scsi.c \
+	sg.c \
+	utils.c \
+	$(NULL)
+
+#
+# The make rules
+#
+
+all: $(LIB)
+
+LIB_SO := $(filter %.so, $(LIB))
+PICS := $(basename $(SOURCES))
+PICS := $(PICS:%=$(BUILD_DIR)/%.o)
+
+$(LIB_SO): $(PICS)
+	@echo '       LINK' $@; \
+	$(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $^ $(LIBRARIES)
+
+$(BUILD_DIR)/%.o: %.c
+	@echo '       CC PIC' $<; \
+	$(CC) -MM $(CFLAGS) -fpic $< | \
+		( $(SED) 's,$*\.o[ :]*,$@: ,g' > $(BUILD_DIR)/$*.d || \
+		$(RM) -f $(BUILD_DIR)/$*.d ); \
+	$(CC) -c $(CFLAGS) -fpic -o $@ $<
+
+clean:
+	@$(RM) -f *.o *.d $(LIB) > /dev/null 2>&1
+
+install: libhbalinux.so
+	@echo '       INSTALL' $<
+	@$(INSTALL) libhbalinux.so $(INSTALL_DIR)
+
+uninstall:
+	@$(RM) -f $(INSTALL_DIR)/libhbalinux.so > /dev/null 2>&1
+
+-include $(PICS:%.o=%.d)
+
+endif
+endif
diff --git a/src/adapt.c b/src/adapt.c
new file mode 100644
index 0000000..cdeba76
--- /dev/null
+++ b/src/adapt.c
@@ -0,0 +1,417 @@
+/*
+ * Copyright (c) 2008, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU Lesser General Public License,
+ * version 2.1, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include "utils.h"
+#include "api_lib.h"
+#include "adapt_impl.h"
+
+static struct sa_table adapter_table;
+static const u_int32_t adapter_handle_offset = 0x100;
+
+#define HBA_SHORT_NAME_LIMIT    64
+
+/*
+ * Support for adapter information.
+ */
+HBA_UINT32
+adapter_get_count(void)
+{
+	return adapter_table.st_limit;
+}
+
+/*
+ * Get adapter name.
+ */
+HBA_STATUS
+adapter_get_name(HBA_UINT32 index, char *buf)
+{
+	HBA_STATUS status;
+	struct adapter_info *ap;
+
+	status = HBA_STATUS_ERROR_ILLEGAL_INDEX;
+	ap = sa_table_lookup(&adapter_table, index);
+	if (ap != NULL) {
+		snprintf(buf, HBA_SHORT_NAME_LIMIT,
+			"%s-%u", ap->ad_name, index);
+		status = HBA_STATUS_OK;
+	}
+	return status;
+}
+
+/*
+ * Add an adapter to the table.
+ */
+HBA_STATUS
+adapter_create(struct adapter_info *ap)
+{
+	int index;
+
+	index = sa_table_append(&adapter_table, ap);
+	if (index < 0)
+		return HBA_STATUS_ERROR;
+	ap->ad_index = index;
+	return HBA_STATUS_OK;
+}
+
+void
+adapter_destroy(struct adapter_info *ap)
+{
+	sa_table_destroy_all(&ap->ad_ports);
+	free(ap);
+}
+
+void
+adapter_destroy_all(void)
+{
+	struct adapter_info *ap;
+	int i;
+
+	for (i = 0; i < adapter_table.st_limit; i++) {
+		ap = adapter_table.st_table[i];
+		if (ap) {
+			adapter_table.st_table[i] = NULL;
+			adapter_destroy(ap);
+		}
+	}
+	sa_table_destroy(&adapter_table);
+}
+
+struct adapter_info *
+adapter_open_handle(HBA_HANDLE handle)
+{
+	return sa_table_lookup(&adapter_table, handle -
+			       adapter_handle_offset);
+}
+
+struct port_info *
+adapter_get_port(HBA_HANDLE handle, HBA_UINT32 port)
+{
+	struct adapter_info *ap;
+	struct port_info *pp = NULL;
+
+	ap = adapter_open_handle(handle);
+	if (ap)
+		pp = sa_table_lookup(&ap->ad_ports, port);
+	return pp;
+}
+
+struct port_info *
+adapter_get_rport(HBA_HANDLE handle, HBA_UINT32 port, HBA_UINT32 rport)
+{
+	struct port_info *pp;
+	struct port_info *rp = NULL;
+
+	pp = adapter_get_port(handle, port);
+	if (pp) {
+		get_rport_info(pp);
+		rp = sa_table_lookup(&pp->ap_rports, rport);
+	}
+	return rp;
+}
+
+/*
+ * Get the Nth discovered port information.
+ */
+struct port_info *
+adapter_get_rport_n(HBA_HANDLE handle, HBA_UINT32 port, HBA_UINT32 n)
+{
+	struct port_info *pp;
+	struct port_info *rp = NULL;
+
+	pp = adapter_get_port(handle, port);
+	if (pp) {
+		get_rport_info(pp);
+		rp = sa_table_lookup_n(&pp->ap_rports, n);
+	}
+	return rp;
+}
+
+static void *
+adapter_target_match(void *rp_arg, void *target_arg)
+{
+	struct port_info *rp = rp_arg;
+
+	if (rp->ap_scsi_target != *(u_int32_t *)target_arg)
+		rp_arg = NULL;
+	return rp_arg;
+}
+
+/*
+ * Get the rport by scsi_target number.
+ */
+struct port_info *
+adapter_get_rport_target(HBA_HANDLE handle, HBA_UINT32 port, HBA_UINT32 n)
+{
+	struct port_info *pp;
+	struct port_info *rp = NULL;
+
+	pp = adapter_get_port(handle, port);
+	if (pp) {
+		get_rport_info(pp);
+		rp = sa_table_search(&pp->ap_rports,
+				     adapter_target_match, &n);
+	}
+	return rp;
+}
+
+static void *
+adapter_wwpn_match(void *rp_arg, void *wwpn_arg)
+{
+	struct port_info *rp = rp_arg;
+
+	if (memcmp(&rp->ap_attr.PortWWN, wwpn_arg, sizeof(HBA_WWN)) != 0)
+		rp_arg = NULL;
+	return rp_arg;
+}
+
+struct port_info *
+adapter_get_rport_by_wwn(struct port_info *pp, HBA_WWN wwpn)
+{
+	struct port_info *rp;
+
+	get_rport_info(pp);
+	rp = sa_table_search(&pp->ap_rports, adapter_wwpn_match, &wwpn);
+	return rp;
+}
+
+static void *
+adapter_fcid_match(void *rp_arg, void *fcid_arg)
+{
+	struct port_info *rp = rp_arg;
+
+	if (rp->ap_attr.PortFcId != *(fc_fid_t *)fcid_arg)
+		rp_arg = NULL;
+	return rp_arg;
+}
+
+struct port_info *
+adapter_get_rport_by_fcid(struct port_info *pp, fc_fid_t fcid)
+{
+	struct port_info *rp;
+
+	get_rport_info(pp);
+	rp = sa_table_search(&pp->ap_rports, adapter_fcid_match, &fcid);
+	return rp;
+}
+
+/*
+ * Open adapter by name.
+ */
+HBA_HANDLE
+adapter_open(char *name)
+{
+	char buf[256];
+	HBA_HANDLE i;
+	HBA_STATUS status;
+
+	for (i = 0; i < adapter_table.st_limit; i++) {
+		status = adapter_get_name(i, buf);
+		if (status != HBA_STATUS_OK)
+			return 0;
+		if (!strcmp(buf, name))
+			return adapter_handle_offset + i;
+	}
+	return 0;
+}
+
+/*
+ * Get port by WWPN.
+ * Returns NULL if WWN not unique.
+ * If countp is non-NULL, the int it points to will be set to the
+ * number found so that the caller can tell if the WWN was ambiguous.
+ */
+struct port_info *
+adapter_get_port_by_wwn(HBA_HANDLE handle, HBA_WWN wwn, int *countp)
+{
+	struct adapter_info *ap;
+	struct port_info *pp_found = NULL;
+	struct port_info *pp;
+	int count = 0;
+	int p;
+
+	ap = adapter_open_handle(handle);
+	if (ap != NULL) {
+		for (p = 0; p < ap->ad_ports.st_limit; p++) {
+			pp = ap->ad_ports.st_table[p];
+			if (pp &&
+			    !memcmp(&pp->ap_attr.PortWWN, &wwn, sizeof(wwn))) {
+				count++;
+				pp_found = pp;
+			}
+		}
+	}
+	if (count > 1)
+		pp_found = NULL;
+	if (countp != NULL)
+		*countp = count;
+	return pp_found;
+}
+
+/*
+ * Open adapter by WWN.
+ */
+HBA_STATUS
+adapter_open_by_wwn(HBA_HANDLE *phandle, HBA_WWN wwn)
+{
+	struct adapter_info *ap;
+	struct port_info *pp;
+	HBA_HANDLE found_handle = 0;
+	int count = 0;
+	HBA_STATUS status;
+	int i;
+	int p;
+
+	for (i = 0; i < adapter_table.st_limit; i++) {
+		ap = adapter_table.st_table[i];
+		if (!ap)
+			continue;
+		if (memcmp(&ap->ad_attr.NodeWWN, &wwn, sizeof(wwn)) == 0) {
+			count++;
+			found_handle = ap->ad_index + adapter_handle_offset;
+		} else {
+			for (p = 0; p < ap->ad_ports.st_limit; p++) {
+				pp = ap->ad_ports.st_table[p];
+				if (!pp)
+					continue;
+				if (memcmp(&pp->ap_attr.PortWWN,
+					   &wwn, sizeof(wwn)) == 0) {
+					count++;
+					found_handle = ap->ad_index +
+						       adapter_handle_offset;
+				}
+			}
+		}
+	}
+
+	*phandle = HBA_HANDLE_INVALID;
+	if (count == 1) {
+		status = HBA_STATUS_OK;
+		*phandle = found_handle;
+	} else if (count > 1) {
+		status = HBA_STATUS_ERROR_AMBIGUOUS_WWN;
+	} else {
+		status = HBA_STATUS_ERROR_ILLEGAL_WWN;
+	}
+	return status;
+}
+
+/*
+ * Close adapter.
+ */
+void
+adapter_close(HBA_HANDLE handle)
+{
+}
+
+/*
+ * Get adapter attributes.
+ */
+HBA_STATUS
+adapter_get_attr(HBA_HANDLE handle, HBA_ADAPTERATTRIBUTES *pattr)
+{
+	struct adapter_info *ap;
+
+	ap = adapter_open_handle(handle);
+	if (ap) {
+		*pattr = ap->ad_attr;       /* struct copy */
+		return HBA_STATUS_OK;
+	}
+	return HBA_STATUS_ERROR;
+}
+
+/*
+ * Get adapter port attributes.
+ */
+HBA_STATUS
+adapter_get_port_attr(HBA_HANDLE handle, HBA_UINT32 port,
+			HBA_PORTATTRIBUTES *pattr)
+{
+	struct port_info *pp;
+
+	pp = adapter_get_port(handle, port);
+	if (pp) {
+		*pattr = pp->ap_attr;       /* struct copy */
+		return HBA_STATUS_OK;
+	}
+	return HBA_STATUS_ERROR;
+}
+
+/*
+ * Get discovered (remote) port attributes.
+ */
+HBA_STATUS
+adapter_get_rport_attr(HBA_HANDLE handle, HBA_UINT32 port, HBA_UINT32 rport,
+			 HBA_PORTATTRIBUTES *pattr)
+{
+	struct port_info *rp;
+
+	rp = adapter_get_rport_n(handle, port, rport);
+	if (rp) {
+		*pattr = rp->ap_attr;       /* struct copy */
+		return HBA_STATUS_OK;
+	}
+	return HBA_STATUS_ERROR;
+}
+
+/*
+ * Get adapter port attributes.
+ */
+HBA_STATUS
+adapter_get_port_attr_by_wwn(HBA_HANDLE handle, HBA_WWN wwn,
+			       HBA_PORTATTRIBUTES *pattr)
+{
+	struct adapter_info *ap;
+	struct port_info *pp;
+	struct port_info *pp_found = NULL;
+	u_int32_t p;
+	int count = 0;
+	HBA_STATUS status;
+
+	ap = adapter_open_handle(handle);
+	if (ap != NULL) {
+		for (p = 0; p < ap->ad_ports.st_limit; p++) {
+			pp = ap->ad_ports.st_table[p];
+			if (pp == NULL)
+				continue;
+			if (!memcmp(&pp->ap_attr.PortWWN, &wwn, sizeof(wwn))) {
+				count++;
+				pp_found = pp;
+			}
+			pp = sa_table_search(&pp->ap_rports,
+					     adapter_wwpn_match,
+					     &wwn);
+			if (pp) {
+				count++;
+				pp_found = pp;
+			}
+		}
+	}
+	pp = pp_found;
+	if (pp != NULL) {
+		if (count > 1) {
+			status = HBA_STATUS_ERROR_AMBIGUOUS_WWN;
+		} else {
+			*pattr = pp->ap_attr;       /* struct copy */
+			status = HBA_STATUS_OK;
+		}
+	} else {
+		status = HBA_STATUS_ERROR_ILLEGAL_WWN;
+	}
+	return status;
+}
+
diff --git a/src/adapt_impl.h b/src/adapt_impl.h
new file mode 100644
index 0000000..b0646b6
--- /dev/null
+++ b/src/adapt_impl.h
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2008, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU Lesser General Public License,
+ * version 2.1, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef _ADAPT_IMPL_H_
+#define _ADAPT_IMPL_H_
+
+#define SYSFS_HOST_DIR     "/sys/class/fc_host"
+#define SYSFS_HBA_DIR      "/sys/class/net"
+#define SYSFS_LUN_DIR      "/sys/class/scsi_device"
+#define SYSFS_MODULE       "/driver/module"
+#define SYSFS_MODULE_VER   "driver/module/version"
+#define SYSFS_RPORT_ROOT       "/sys/class/fc_remote_ports"
+#define SYSFS_RPORT_DIR        "rport-%u:%u-%u" /* host, chan, rport */
+
+struct hba_info {
+	u_int32_t	domain;
+	u_int32_t	bus;
+	u_int32_t	dev;
+	u_int32_t	func;
+	u_int32_t	vendor_id;
+	u_int32_t	subsystem_vendor_id;
+	u_int32_t	subsystem_device_id;
+	u_int32_t	device_id;
+	u_int32_t	device_class;
+	u_int32_t	irq;
+	char		Manufacturer[64];
+	char		SerialNumber[64];
+	char		Model[256];
+	char		ModelDescription[256];
+	char		HardwareVersion[256];
+	char		OptionROMVersion[256];
+	char		FirmwareVersion[256];
+	u_int32_t	VendorSpecificID;
+	u_int32_t	NumberOfPorts;
+};
+
+#define MAX_DRIVER_NAME_LEN	20
+#define ARRAY_SIZE(a)		(sizeof(a)/sizeof((a)[0]))
+
+/* fc_port_type: copied from scsi_transport_fc.h */
+enum fc_port_type {
+	FC_PORTTYPE_UNKNOWN,
+	FC_PORTTYPE_OTHER,
+	FC_PORTTYPE_NOTPRESENT,
+	FC_PORTTYPE_NPORT,		/* Attached to FPort */
+	FC_PORTTYPE_NLPORT,		/* (Public) Loop w/ FLPort */
+	FC_PORTTYPE_LPORT,		/* (Private) Loop w/o FLPort */
+	FC_PORTTYPE_PTP,		/* Point to Point w/ another NPort */
+	FC_PORTTYPE_NPIV,		/* VPORT based on NPIV */
+};
+
+#define fc_enum_name_search(title, table_type, table) \
+static const enum fc_port_type get_fc_##title##_value(const char *table_key) \
+{ \
+	int i; enum fc_port_type value = 0; \
+	for (i = 0; i < ARRAY_SIZE(table); i++) { \
+		if (!strcmp(table[i].name, table_key)) { \
+			value = table[i].value; \
+			break; \
+		} \
+	} \
+	return value; \
+}
+
+HBA_STATUS sysfs_get_port_stats(char *dir, HBA_PORTSTATISTICS *sp);
+HBA_STATUS sysfs_get_port_fc4stats(char *dir, HBA_FC4STATISTICS *fc4sp);
+
+extern struct sa_nameval port_states_table[];
+extern struct sa_nameval port_speeds_table[];
+extern void adapter_scan(void);
+extern int sys_read_wwn(const char *, const char *, HBA_WWN *);
+extern HBA_STATUS find_pci_device(struct hba_info *);
+
+/*
+ * per-adapter interface.
+ */
+
+/*
+ * Information about a particular adapter.
+ */
+struct adapter_info {
+    u_int32_t               ad_index;       /* adapter's library index */
+    u_int32_t               ad_kern_index;  /* adapter's kernel index */
+    const char              *ad_name;       /* adapter driver name */
+    struct sa_table         ad_ports;       /* table of ports */
+    u_int32_t               ad_port_count;  /* adapter's number of ports */
+    HBA_ADAPTERATTRIBUTES   ad_attr;        /* HBA-API attributes */
+};
+
+/*
+ * Information about a port on an adapter or a discovered remote port.
+ */
+struct port_info {
+    struct adapter_info     *ap_adapt;
+    u_int32_t               ap_index;
+    u_int32_t               ap_disc_index;  /* discovered port index */
+    u_int32_t               ap_scsi_target; /* SCSI target index (rports) */
+    u_int32_t               ap_kern_hba;    /* kernel HBA index (rports) */
+    struct sa_table         ap_rports;      /* discovered ports */
+    HBA_PORTATTRIBUTES      ap_attr;        /* HBA-API port attributes */
+    char                    host_dir[80];   /* sysfs directory save area */
+};
+
+/*
+ * Internal functions.
+ */
+HBA_UINT32 adapter_get_count(void);
+HBA_STATUS adapter_get_name(HBA_UINT32 index, char *);
+struct port_info *adapter_get_port_by_wwn(HBA_HANDLE, HBA_WWN, int *countp);
+HBA_STATUS adapter_create(struct adapter_info *);
+void adapter_destroy(struct adapter_info *);
+void adapter_destroy_all(void);
+struct adapter_info *adapter_open_handle(HBA_HANDLE);
+struct port_info *adapter_get_port(HBA_HANDLE, HBA_UINT32 port);
+struct port_info *adapter_get_rport(HBA_HANDLE, HBA_UINT32, HBA_UINT32);
+struct port_info *adapter_get_rport_n(HBA_HANDLE, HBA_UINT32, HBA_UINT32);
+struct port_info *adapter_get_rport_target(HBA_HANDLE, HBA_UINT32, HBA_UINT32);
+struct port_info *adapter_get_rport_by_wwn(struct port_info *, HBA_WWN);
+struct port_info *adapter_get_rport_by_fcid(struct port_info *, fc_fid_t);
+void get_rport_info(struct port_info *);
+void sg_get_dev_id(const char *name, char *buf, size_t result_len);
+void copy_wwn(HBA_WWN *dest, fc_wwn_t src);
+int is_wwn_nonzero(HBA_WWN *wwn);
+HBA_STATUS sg_issue_read_capacity(const char *, void *, HBA_UINT32 *,
+			HBA_UINT8 *, void *, HBA_UINT32 *);
+HBA_STATUS sg_issue_report_luns(const char *, void *, HBA_UINT32 *,
+			HBA_UINT8 *, void *, HBA_UINT32 *);
+
+/*
+ * Library functions.
+ */
+HBA_HANDLE adapter_open(char *name);
+HBA_STATUS adapter_open_by_wwn(HBA_HANDLE *, HBA_WWN);
+void adapter_close(HBA_HANDLE);
+HBA_STATUS adapter_get_attr(HBA_HANDLE, HBA_ADAPTERATTRIBUTES *);
+HBA_STATUS adapter_get_port_attr(HBA_HANDLE, HBA_UINT32 port,
+				HBA_PORTATTRIBUTES *);
+HBA_STATUS adapter_get_port_attr_by_wwn(HBA_HANDLE, HBA_WWN,
+				HBA_PORTATTRIBUTES *);
+HBA_STATUS adapter_get_rport_attr(HBA_HANDLE, HBA_UINT32 port,
+				HBA_UINT32 rport, HBA_PORTATTRIBUTES *);
+HBA_STATUS get_port_statistics(HBA_HANDLE, HBA_UINT32 port,
+				HBA_PORTSTATISTICS *);
+HBA_STATUS get_port_fc4_statistics(HBA_HANDLE, HBA_WWN,
+				HBA_UINT8 fc4_type, HBA_FC4STATISTICS *);
+HBA_STATUS scsi_read_capacity_v1(HBA_HANDLE, HBA_WWN, HBA_UINT64,
+				void *, HBA_UINT32, void *, HBA_UINT32);
+HBA_STATUS scsi_read_capacity_v2(HBA_HANDLE, HBA_WWN, HBA_WWN,
+			HBA_UINT64, void *, HBA_UINT32 *, HBA_UINT8 *,
+			void *, HBA_UINT32 *);
+HBA_STATUS scsi_inquiry_v1(HBA_HANDLE, HBA_WWN, HBA_UINT64, HBA_UINT8,
+			HBA_UINT32, void *, HBA_UINT32, void *, HBA_UINT32);
+HBA_STATUS scsi_inquiry_v2(HBA_HANDLE, HBA_WWN, HBA_WWN, HBA_UINT64,
+			HBA_UINT8, HBA_UINT8, void *, HBA_UINT32 *,
+			HBA_UINT8 *, void *, HBA_UINT32 *);
+HBA_STATUS scsi_report_luns_v1(HBA_HANDLE, HBA_WWN,
+			void *, HBA_UINT32, void *, HBA_UINT32);
+HBA_STATUS scsi_report_luns_v2(HBA_HANDLE, HBA_WWN, HBA_WWN,
+			void *, HBA_UINT32 *, HBA_UINT8 *,
+			void *, HBA_UINT32 *);
+HBA_STATUS sg_issue_inquiry(const char *, HBA_UINT8, HBA_UINT8,
+		void *, HBA_UINT32 *, HBA_UINT8 *, void *, HBA_UINT32 *);
+
+void adapter_init(void);
+void adapter_shutdown(void);
+
+/* struct port_stats; */
+
+#endif /* _ADAPT_IMPL_H_ */
diff --git a/src/api_lib.h b/src/api_lib.h
new file mode 100644
index 0000000..d625a79
--- /dev/null
+++ b/src/api_lib.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2008, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU Lesser General Public License,
+ * version 2.1, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef _API_LIB_H_
+#define _API_LIB_H_
+
+/*
+ * Definitions used by the OpenFC-specific library for the SNIA HBA-API.
+ */
+#define	HBA_API_VENDOR        "Open-FC.org"
+#define	HBA_API_VERSION       "2.2"
+#define	HBA_API_VENDOR_RURL   "org.open-fc"	/* reversed URL */
+
+#endif /* _API_LIB_H_ */
diff --git a/src/bind.c b/src/bind.c
new file mode 100644
index 0000000..eaf8549
--- /dev/null
+++ b/src/bind.c
@@ -0,0 +1,353 @@
+/*
+ * Copyright (c) 2008, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU Lesser General Public License,
+ * version 2.1, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include "utils.h"
+#include "api_lib.h"
+#include "adapt_impl.h"
+#include "bind_impl.h"
+
+/*
+ * Binding capabilities we understand.
+ */
+#define BINDING_CAPABILITIES   (HBA_CAN_BIND_TO_D_ID | \
+				HBA_CAN_BIND_TO_WWPN | \
+				HBA_CAN_BIND_TO_WWNN)
+#define SYSFS_BIND		"tgtid_bind_type"
+
+/*
+ * Name-value strings for kernel bindings.
+ * The first word of the strings must exactly match those in
+ * Linux's drivers/scsi/scsi_transport_fc
+ */
+static struct sa_nameval binding_types_table[] = {
+	{ "none",                           0 },
+	{ "wwpn (World Wide Port Name)",    HBA_CAN_BIND_TO_WWPN },
+	{ "wwnn (World Wide Node Name)",    HBA_CAN_BIND_TO_WWNN },
+	{ "port_id (FC Address)",           HBA_CAN_BIND_TO_D_ID },
+	{ NULL,                             0 }
+};
+
+/*
+ * Context for LUN binding reader.
+ */
+struct binding_context {
+	HBA_HANDLE            oc_handle;
+	int                   oc_kern_hba;  /* kernel HBA number */
+	int                   oc_port;
+	int                   oc_target;
+	int                   oc_lun;
+	u_int32_t             oc_count;
+	u_int32_t             oc_limit;
+	u_int32_t             oc_ver;
+	void                  *oc_entries;
+	HBA_STATUS            oc_status;
+	char                  oc_sg[32];    /* SCSI-generic dev name */
+	HBA_SCSIID            *oc_scp;      /* place for OS device name */
+	struct port_info *oc_rport;    /* target remote port, if known */
+};
+
+/*
+ * Get binding capability.
+ * We currently don't have a way to get this from the driver.
+ * Instead, we hardcode what we know about Linux's capabilities.
+ * We don't care which HBA is specified, except to return the correct error.
+ */
+HBA_STATUS
+get_binding_capability(HBA_HANDLE handle, HBA_WWN wwn, HBA_BIND_CAPABILITY *cp)
+{
+	struct port_info *pp;
+	int count = 0;
+
+	pp = adapter_get_port_by_wwn(handle, wwn, &count);
+	if (count > 1)
+		return HBA_STATUS_ERROR_AMBIGUOUS_WWN;
+	else if (pp == NULL)
+		return HBA_STATUS_ERROR_ILLEGAL_WWN;
+	*cp = BINDING_CAPABILITIES;
+	return HBA_STATUS_OK;
+}
+
+/*
+ * Get binding support.
+ */
+HBA_STATUS
+get_binding_support(HBA_HANDLE handle, HBA_WWN wwn, HBA_BIND_CAPABILITY *cp)
+{
+	struct port_info *pp;
+	char dir[50];
+	char bind[50];
+	int count = 0;
+
+	pp = adapter_get_port_by_wwn(handle, wwn, &count);
+	if (count > 1)
+		return HBA_STATUS_ERROR_AMBIGUOUS_WWN;
+	else if (pp == NULL)
+		return HBA_STATUS_ERROR_ILLEGAL_WWN;
+	snprintf(dir, sizeof(dir), SYSFS_HOST_DIR "/host%u", pp->ap_kern_hba);
+	if (sa_sys_read_line(dir, SYSFS_BIND, bind, sizeof(bind)) == 0)
+		sa_enum_encode(binding_types_table, bind, cp);
+	return HBA_STATUS_OK;
+}
+
+/*
+ * Set binding support.
+ */
+HBA_STATUS
+set_binding_support(HBA_HANDLE handle, HBA_WWN wwn, HBA_BIND_CAPABILITY flags)
+{
+	struct port_info *pp;
+	int count = 0;
+	char dir[50];
+	char buf[50];
+	const char *bind;
+
+	pp = adapter_get_port_by_wwn(handle, wwn, &count);
+	if (count > 1)
+		return HBA_STATUS_ERROR_AMBIGUOUS_WWN;
+	if (pp == NULL)
+		return HBA_STATUS_ERROR_ILLEGAL_WWN;
+	if ((flags & BINDING_CAPABILITIES) != flags)
+		return HBA_STATUS_ERROR_NOT_SUPPORTED;
+	bind = sa_enum_decode(buf, sizeof(buf), binding_types_table, flags);
+	snprintf(dir, sizeof(dir), SYSFS_HOST_DIR "/host%u", pp->ap_kern_hba);
+	if (strstr(bind, "Unknown") != NULL)
+		return HBA_STATUS_ERROR_NOT_SUPPORTED;
+	if (sa_sys_write_line(dir, SYSFS_BIND, bind) == 0)
+		return HBA_STATUS_ERROR_INCAPABLE;
+	return HBA_STATUS_OK;
+}
+
+static int
+get_binding_os_names(struct dirent *dp, void *arg)
+{
+	struct binding_context *cp = arg;
+	char *name = dp->d_name;
+	char *sep;
+
+	sep = strchr(name, ':');
+	if (dp->d_type == DT_LNK && sep != NULL) {
+		*sep = '\0';                /* replace colon */
+		if (strcmp(name, "block") == 0) {
+			snprintf(cp->oc_scp->OSDeviceName,
+				 sizeof(cp->oc_scp->OSDeviceName),
+				 "/dev/%s", sep + 1);
+		} else if (strcmp(name, "scsi_generic") == 0) {
+			snprintf(cp->oc_sg,
+				 sizeof(cp->oc_sg),
+				 "/dev/%s", sep + 1);
+		}
+		*sep = ':';                 /* not really needed */
+	}
+	return 0;
+}
+
+static int
+get_binding_target_mapping(struct dirent *dp, void *ctxt_arg)
+{
+	struct binding_context *cp = ctxt_arg;
+	struct port_info *pp;
+	HBA_FCPSCSIENTRY *sp;
+	HBA_FCPSCSIENTRYV2 *s2p;
+	HBA_SCSIID *scp = NULL;
+	HBA_FCPID *fcp = NULL;
+	HBA_LUID *luid = NULL;
+	char name[50];
+	u_int32_t hba = -1;
+	u_int32_t port = -1;
+	u_int32_t tgt = -1;
+	u_int32_t lun = -1;
+
+	/*
+	 * Parse directory entry name to see if it matches
+	 * <hba>:<port>:<target>:<lun>.
+	 */
+	if (sscanf(dp->d_name, "%u:%u:%u:%u", &hba, &port, &tgt, &lun) != 4)
+		return 0;
+
+	if (hba != cp->oc_kern_hba ||
+	    (port != cp->oc_port && cp->oc_port != -1) ||
+	    (tgt != cp->oc_target && cp->oc_target != -1) ||
+	    (lun != cp->oc_lun && cp->oc_lun != -1)) {
+		return 0;
+	}
+
+	/*
+	 * Name matches.  Add to count and to mapping list if there's room.
+	 */
+	if (cp->oc_count < cp->oc_limit) {
+
+		switch (cp->oc_ver) {
+		case 1:
+			sp = &((HBA_FCPSCSIENTRY *)
+				cp->oc_entries)[cp->oc_count];
+			scp = &sp->ScsiId;
+			fcp = &sp->FcpId;
+			luid = NULL;
+			break;
+		case 2:
+			s2p = &((HBA_FCPSCSIENTRYV2 *)
+				cp->oc_entries)[cp->oc_count];
+			scp = &s2p->ScsiId;
+			fcp = &s2p->FcpId;
+			luid = &s2p->LUID;
+			break;
+		default:
+			fprintf(stderr, "*** Fatal! ***\n");
+			break;
+		}
+		pp = cp->oc_rport;
+		if (pp == NULL)
+			pp = adapter_get_rport_target(cp->oc_handle,
+							port, tgt);
+		if (pp != NULL) {
+			fcp->FcId = pp->ap_attr.PortFcId;
+			fcp->NodeWWN = pp->ap_attr.NodeWWN;
+			fcp->PortWWN = pp->ap_attr.PortWWN;
+			fcp->FcpLun = (HBA_UINT64) lun << 48;
+		}
+
+		/*
+		 * Find OS device name by searching for symlink block:<device>
+		 * and SG name by searching for scsi_generic:<name>
+		 * in device subdirectory.
+		 */
+		snprintf(name, sizeof(name),
+			 SYSFS_LUN_DIR "/%s/device", dp->d_name);
+		cp->oc_sg[0] = '\0';
+		cp->oc_scp = scp;
+		scp->OSDeviceName[0] = '\0';
+		sa_dir_read(name, get_binding_os_names, cp);
+		scp->ScsiBusNumber = hba;
+		scp->ScsiTargetNumber = tgt;
+		scp->ScsiOSLun = lun;
+
+		/*
+		 * find the LUN ID information by using scsi_generic I/O.
+		 */
+		if (luid != NULL && cp->oc_sg[0] != '\0')
+			sg_get_dev_id(cp->oc_sg, luid->buffer,
+					  sizeof(luid->buffer));
+	}
+	cp->oc_count++;
+	return 0;
+}
+
+/*
+ * Get FCP target mapping.
+ */
+HBA_STATUS
+get_binding_target_mapping_v1(HBA_HANDLE handle, HBA_FCPTARGETMAPPING *map)
+{
+	struct binding_context ctxt;
+	struct adapter_info *ap;
+
+	ap = adapter_open_handle(handle);
+	if (ap == NULL)
+		return HBA_STATUS_ERROR_INVALID_HANDLE;
+	memset(&ctxt, 0, sizeof(ctxt));
+	ctxt.oc_handle = handle;
+	ctxt.oc_kern_hba = ap->ad_kern_index;
+	ctxt.oc_port = -1;
+	ctxt.oc_target = -1;
+	ctxt.oc_lun = -1;
+	ctxt.oc_limit = map->NumberOfEntries;
+	ctxt.oc_ver = 1;
+	ctxt.oc_entries = map->entry;
+	ctxt.oc_status = HBA_STATUS_OK;
+	memset(map->entry, 0, sizeof(map->entry[0]) * ctxt.oc_limit);
+	sa_dir_read(SYSFS_LUN_DIR, get_binding_target_mapping, &ctxt);
+	map->NumberOfEntries = ctxt.oc_count;
+	if (ctxt.oc_status == HBA_STATUS_OK && ctxt.oc_count > ctxt.oc_limit)
+		ctxt.oc_status = HBA_STATUS_ERROR_MORE_DATA;
+	return ctxt.oc_status;
+}
+
+/*
+ * Get FCP target mapping.
+ */
+HBA_STATUS
+get_binding_target_mapping_v2(HBA_HANDLE handle, HBA_WWN wwn,
+			       HBA_FCPTARGETMAPPINGV2 *map)
+{
+	struct binding_context ctxt;
+	struct adapter_info *ap;
+	struct port_info *pp;
+
+	pp = adapter_get_port_by_wwn(handle, wwn, NULL);
+	if (pp == NULL)
+		return HBA_STATUS_ERROR_INVALID_HANDLE;
+	ap = pp->ap_adapt;
+	if (ap == NULL)
+		return HBA_STATUS_ERROR_INVALID_HANDLE;
+	memset(&ctxt, 0, sizeof(ctxt));
+	ctxt.oc_handle = handle;
+	ctxt.oc_kern_hba = ap->ad_kern_index;
+	ctxt.oc_port = pp->ap_index;
+	ctxt.oc_target = -1;
+	ctxt.oc_lun = -1;
+	ctxt.oc_limit = map->NumberOfEntries;
+	ctxt.oc_ver = 2;
+	ctxt.oc_entries = map->entry;
+	ctxt.oc_status = HBA_STATUS_OK;
+	memset(map->entry, 0, sizeof(map->entry[0]) * ctxt.oc_limit);
+	sa_dir_read(SYSFS_LUN_DIR, get_binding_target_mapping, &ctxt);
+	map->NumberOfEntries = ctxt.oc_count;
+	return ctxt.oc_status;
+}
+
+/*
+ * Get LUN scsi-generic device name.
+ */
+int
+get_binding_sg_name(struct port_info *lp, HBA_WWN disc_wwpn,
+		     HBA_UINT64 fc_lun, char *buf, size_t len)
+{
+	struct binding_context ctxt;
+	struct port_info *rp;
+	HBA_FCPSCSIENTRYV2 entry;
+
+	/*
+	 * find discovered (remote) port.
+	 */
+	rp = adapter_get_rport_by_wwn(lp, disc_wwpn);
+	if (rp == NULL)
+		return HBA_STATUS_ERROR_ILLEGAL_WWN;
+
+	/*
+	 * Check for LUN more than 1023 or multi-level.
+	 */
+	if (fc_lun & ((0xfc01ULL << 48) - 1))
+		return HBA_STATUS_ERROR;
+	memset(&ctxt, 0, sizeof(ctxt));
+	memset(&entry, 0, sizeof(entry));
+	ctxt.oc_rport = rp;
+	ctxt.oc_kern_hba = rp->ap_kern_hba;
+	ctxt.oc_port = rp->ap_index;
+	ctxt.oc_target = rp->ap_scsi_target;
+	if (ctxt.oc_target == -1)
+		return ENOENT;
+	ctxt.oc_lun = fc_lun >> 48;
+	ctxt.oc_limit = 1;
+	ctxt.oc_ver = 1;
+	ctxt.oc_entries = &entry;
+	sa_dir_read(SYSFS_LUN_DIR, get_binding_target_mapping, &ctxt);
+	if (ctxt.oc_count != 1)
+		return ENOENT;
+	strncpy(buf, ctxt.oc_sg, len);
+	return 0;
+}
diff --git a/src/bind_impl.h b/src/bind_impl.h
new file mode 100644
index 0000000..7bcff02
--- /dev/null
+++ b/src/bind_impl.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2008, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU Lesser General Public License,
+ * version 2.1, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef _BIND_IMPL_H_
+#define _BIND_IMPL_H_
+
+HBA_STATUS get_binding_capability(HBA_HANDLE, HBA_WWN, HBA_BIND_CAPABILITY *);
+HBA_STATUS get_binding_support(HBA_HANDLE, HBA_WWN, HBA_BIND_CAPABILITY *);
+HBA_STATUS set_binding_support(HBA_HANDLE, HBA_WWN, HBA_BIND_CAPABILITY);
+HBA_STATUS get_binding_target_mapping_v1(HBA_HANDLE, HBA_FCPTARGETMAPPING *);
+HBA_STATUS get_binding_target_mapping_v2(HBA_HANDLE, HBA_WWN,
+					  HBA_FCPTARGETMAPPINGV2 *);
+int get_binding_sg_name(struct port_info *,
+			HBA_WWN, HBA_UINT64, char *, size_t);
+
+#endif /* _BIND_IMPL_H_ */
diff --git a/src/lib.c b/src/lib.c
new file mode 100644
index 0000000..623b126
--- /dev/null
+++ b/src/lib.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2008, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU Lesser General Public License,
+ * version 2.1, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#define _XOPEN_SOURCE 500        /* for strptime() */
+#include "utils.h"
+#include "api_lib.h"
+#include "adapt_impl.h"
+#include "bind_impl.h"
+
+/**
+ * Return the version of the SNIA HBA-API supported by this library.
+ */
+static HBA_UINT32 get_library_version()
+{
+	return HBA_LIBVERSION;
+}
+
+/*
+ * When HBA_GetVendorLibraryAttributes() is called,
+ * it does not dispatch to the library entry point at
+ * .GetVendorLibraryAttributesHandler. Thus this
+ * routine can never be entered. -[sma]
+ */
+#if 0
+/**
+ * Get the library attributes.
+ * @param ap library attributes pointer.
+ * @returns 0 or error code.
+ */
+static HBA_STATUS get_vendor_lib_attrs(HBA_LIBRARYATTRIBUTES *ap)
+{
+	memset(ap, 0, sizeof(*ap));
+	if (strptime(BUILD_DATE, "%Y/%m/%d %T %Z", &ap->build_date) == NULL)
+		memset(&ap->build_date, 0, sizeof(ap->build_date));
+	strcpy(ap->VName, HBA_API_VENDOR);
+	strcpy(ap->VVersion, HBA_API_VERSION);
+	return HBA_STATUS_OK;
+}
+#endif
+
+/*
+ * initialize the library after load.
+ */
+static HBA_STATUS load_library(void)
+{
+	adapter_init();
+	return HBA_STATUS_OK;
+}
+
+static HBA_STATUS free_library(void)
+{
+	adapter_shutdown();
+	adapter_destroy_all();
+	return HBA_STATUS_OK;
+}
+
+static HBA_ENTRYPOINTSV2 vendor_lib_entrypoints = {
+    .GetVersionHandler =                       get_library_version,
+    .LoadLibraryHandler =                      load_library,
+    .FreeLibraryHandler =                      free_library,
+    .GetNumberOfAdaptersHandler =              adapter_get_count,
+    .GetAdapterNameHandler =                   adapter_get_name,
+    .OpenAdapterHandler =                      adapter_open,
+    .CloseAdapterHandler =                     adapter_close,
+    .GetAdapterAttributesHandler =             adapter_get_attr,
+    .GetAdapterPortAttributesHandler =         adapter_get_port_attr,
+    .GetPortStatisticsHandler =                get_port_statistics,
+    .GetDiscoveredPortAttributesHandler =      adapter_get_rport_attr,
+
+    .GetPortAttributesByWWNHandler =           NULL,
+					/* adapter_get_port_attr_by_wwn, */
+    /* Next function deprecated but still supported */
+    .SendCTPassThruHandler =                   NULL,
+    .RefreshInformationHandler =               NULL,
+    .ResetStatisticsHandler =                  NULL,
+    /* Next function deprecated but still supported */
+    .GetFcpTargetMappingHandler =              get_binding_target_mapping_v1,
+    /* Next function depricated but still supported */
+    .GetFcpPersistentBindingHandler =          NULL,
+    .GetEventBufferHandler =                   NULL,
+    .SetRNIDMgmtInfoHandler =                  NULL,
+    .GetRNIDMgmtInfoHandler =                  NULL,
+    /* Next function deprecated but still supported */
+    .SendRNIDHandler =                         NULL,
+    .ScsiInquiryHandler =                      scsi_inquiry_v1,
+    .ReportLUNsHandler =                       scsi_report_luns_v1,
+    .ReadCapacityHandler =                     scsi_read_capacity_v1,
+
+    /* V2 handlers */
+    .OpenAdapterByWWNHandler =                 NULL,
+					/* adapter_open_by_wwn, */
+    .GetFcpTargetMappingV2Handler =            get_binding_target_mapping_v2,
+    .SendCTPassThruV2Handler =                 NULL,
+    .RefreshAdapterConfigurationHandler =      NULL,
+    .GetBindingCapabilityHandler =             NULL,
+					/* get_binding_capability, */
+    .GetBindingSupportHandler =                NULL,
+					/* get_binding_support, */
+    .SetBindingSupportHandler =                NULL,
+					/* set_binding_support, */
+    .SetPersistentBindingV2Handler =           NULL,
+    .GetPersistentBindingV2Handler =           NULL,
+    .RemovePersistentBindingHandler =          NULL,
+    .RemoveAllPersistentBindingsHandler =      NULL,
+    .SendRNIDV2Handler =                       NULL,
+    .ScsiInquiryV2Handler =                    scsi_inquiry_v2,
+    .ScsiReportLUNsV2Handler =                 scsi_report_luns_v2,
+    .ScsiReadCapacityV2Handler =               scsi_read_capacity_v2,
+    .GetVendorLibraryAttributesHandler =       NULL,
+					/* get_vendor_lib_attrs, */
+    .RemoveCallbackHandler =                   NULL,
+    .RegisterForAdapterAddEventsHandler =      NULL,
+    .RegisterForAdapterEventsHandler =         NULL,
+    .RegisterForAdapterPortEventsHandler =     NULL,
+    .RegisterForAdapterPortStatEventsHandler = NULL,
+    .RegisterForTargetEventsHandler =          NULL,
+    .RegisterForLinkEventsHandler =            NULL,
+    .SendRPLHandler =                          NULL,
+    .SendRPSHandler =                          NULL,
+    .SendSRLHandler =                          NULL,
+    .SendLIRRHandler =                         NULL,
+    .GetFC4StatisticsHandler =                 get_port_fc4_statistics,
+    .GetFCPStatisticsHandler =                 NULL,
+    .SendRLSHandler =                          NULL,
+};
+
+/**
+ * Function called by a version 1 common HBAAPI library to get our entry points.
+ *
+ * @arg ep pointer to entrypoints structure where we store our
+ *  function pointers.
+ * @returns HBA_STATUS.
+ */
+HBA_STATUS HBA_RegisterLibrary(HBA_ENTRYPOINTS *ep)
+{
+	memcpy(ep, &vendor_lib_entrypoints, sizeof(HBA_ENTRYPOINTS));
+	return HBA_STATUS_OK;
+}
+
+/**
+ * Function called by the common HBAAPI library to get our entry points.
+ *
+ * @arg ep pointer to entrypoints structure where we store our
+ *  function pointers.
+ * @returns HBA_STATUS.
+ */
+HBA_STATUS HBA_RegisterLibraryV2(HBA_ENTRYPOINTSV2 *ep)
+{
+	*ep = vendor_lib_entrypoints;  /* structure copy */
+	return HBA_STATUS_OK;
+}
+
diff --git a/src/lport.c b/src/lport.c
new file mode 100644
index 0000000..9c47887
--- /dev/null
+++ b/src/lport.c
@@ -0,0 +1,545 @@
+/*
+ * Copyright (c) 2008, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU Lesser General Public License,
+ * version 2.1, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include "utils.h"
+#include "api_lib.h"
+#include "adapt_impl.h"
+
+#ifndef HBA_STATUS_ERROR_ILLEGAL_FCID
+#define HBA_STATUS_ERROR_ILLEGAL_FCID 33	/* defined after HBA-API 2.2 */
+#endif
+#define SEND_CT_TIMEOUT		(3 * 1000)	/* timeout in milliseconds */
+
+/*
+ * The following are temporary settings until we can find a way to
+ * collect these information.
+ */
+#define HBA_MODEL               "(Unknown)"
+#define HBA_ROM_VERSION         "(None)"
+#define HBA_FW_VERSION          "(None)"
+#define HBA_VENDOR_SPECIFIC_ID  123456
+
+/*
+ * Convert fc_port_type values to ascii string name.
+ * (This table is copied from scsi_transport_fc.c).
+ */
+static struct {
+	enum fc_port_type	value;
+	char			*name;
+} port_types_table[] = {
+    { FC_PORTTYPE_UNKNOWN,     "Unknown" },
+    { FC_PORTTYPE_OTHER,       "Other" },
+    { FC_PORTTYPE_NOTPRESENT,  "Not Present" },
+    { FC_PORTTYPE_NPORT,       "NPort (fabric via point-to-point)" },
+    { FC_PORTTYPE_NLPORT,      "NLPort (fabric via loop)" },
+    { FC_PORTTYPE_LPORT,       "LPort (private loop)" },
+    { FC_PORTTYPE_PTP,         "Point-To-Point (direct nport connection)" },
+    { FC_PORTTYPE_NPIV,        "NPIV VPORT" },
+};
+fc_enum_name_search(port_type, fc_port_type, port_types_table)
+#define FC_PORTTYPE_MAX_NAMELEN         50
+
+/*
+ * table of /sys port state strings to HBA-API values.
+ */
+struct sa_nameval port_states_table[] = {
+	{ "Not Present",    HBA_PORTSTATE_UNKNOWN },
+	{ "Online",         HBA_PORTSTATE_ONLINE },
+	{ "Offline",        HBA_PORTSTATE_OFFLINE },
+	{ "Blocked",        HBA_PORTSTATE_UNKNOWN },
+	{ "Bypassed",       HBA_PORTSTATE_BYPASSED },
+	{ "Diagnostics",    HBA_PORTSTATE_DIAGNOSTICS },
+	{ "Linkdown",       HBA_PORTSTATE_LINKDOWN },
+	{ "Error",          HBA_PORTSTATE_ERROR },
+	{ "Loopback",       HBA_PORTSTATE_LOOPBACK },
+	{ "Deleted",        HBA_PORTSTATE_UNKNOWN },
+	{ NULL, 0 }
+};
+
+/*
+ * table of /sys port speed strings to HBA-API values.
+ */
+struct sa_nameval port_speeds_table[] = {
+	{ "10 Gbit",        HBA_PORTSPEED_10GBIT },
+	{ "2 Gbit",         HBA_PORTSPEED_2GBIT },
+	{ "1 Gbit",         HBA_PORTSPEED_1GBIT },
+	{ "Not Negotiated", HBA_PORTSPEED_NOT_NEGOTIATED },
+	{ "Unknown",        HBA_PORTSPEED_UNKNOWN },
+	{ NULL, 0 }
+};
+
+/*
+ * Code for OpenFC-supported adapters.
+ */
+
+static int
+counting_rports(struct dirent *dp, void *arg)
+{
+	int *count = (int *)arg;
+
+	if (!strstr(dp->d_name, "rport-"))
+		return HBA_STATUS_OK;
+	(*count)++;
+	return HBA_STATUS_OK;
+}
+
+static int
+sysfs_scan(struct dirent *dp, void *arg)
+{
+	int lport_count = 0;
+	HBA_ADAPTERATTRIBUTES *atp;
+	HBA_PORTATTRIBUTES *pap;
+	HBA_WWN wwnn;
+	struct hba_info hba_info;
+	struct adapter_info *ap;
+	struct port_info *pp;
+	char host_dir[80], hba_dir[80], drv_dir[80];
+	char ifname[20], buf[256];
+	char *driverName;
+	int data[32], rc, i;
+
+	/* Found a local port! */
+	lport_count++;
+
+	/*
+	 * Create a new HBA entry (ap) for the local port
+	 * We will create a new HBA entry for each local port.
+	 */
+	ap = malloc(sizeof(*ap));
+	if (!ap) {
+		fprintf(stderr, "%s: malloc failed, errno=0x%x\n",
+			__func__, errno);
+		return HBA_STATUS_ERROR;
+	}
+	memset(ap, 0, sizeof(*ap));
+	ap->ad_kern_index = atoi(dp->d_name + sizeof("host") - 1);
+	ap->ad_port_count = 1;
+
+	/* atp points to the HBA attributes structure */
+	atp = &ap->ad_attr;
+
+	/*
+	 * Create a new local port entry
+	 */
+	pp = malloc(sizeof(*pp));
+	if (pp == NULL) {
+		fprintf(stderr,
+			"%s: malloc for local port %d failed,"
+			" errno=0x%x\n", __func__,
+			ap->ad_port_count - 1, errno);
+		return HBA_STATUS_ERROR;
+	}
+
+	memset(pp, 0, sizeof(*pp));
+	pp->ap_adapt = ap;
+	pp->ap_index = ap->ad_port_count - 1;
+	pp->ap_kern_hba = atoi(dp->d_name + sizeof("host") - 1);
+
+	/* pap points to the local port attributes structure */
+	pap = &pp->ap_attr;
+
+	/* Construct the host directory name from the input name */
+	snprintf(host_dir, sizeof(host_dir),
+		SYSFS_HOST_DIR "/%s", dp->d_name);
+
+	/* Get the ifname from the symbolic_name */
+	rc = sa_sys_read_line(host_dir, "symbolic_name", buf, sizeof(buf));
+	sa_strncpy_safe(ifname, sizeof(ifname),
+			strstr(buf, "over") + 5, sizeof(ifname));
+	snprintf(hba_dir, sizeof(hba_dir),
+		 SYSFS_HBA_DIR "/%s/device", ifname);
+
+	/*
+	 * Save the host directory and the hba directory
+	 * in local port structure
+	 */
+	sa_strncpy_safe(pp->host_dir, sizeof(pp->host_dir),
+			host_dir, sizeof(host_dir));
+
+	/* Get PortSymbolicName */
+	sa_strncpy_safe(pap->PortSymbolicName, sizeof(pap->PortSymbolicName),
+			buf, sizeof(buf));
+
+	/* Get NodeWWN */
+	rc = sys_read_wwn(pp->host_dir, "node_name", &wwnn);
+	memcpy(&pap->NodeWWN, &wwnn, sizeof(wwnn));
+
+	/* Get PortWWN */
+	rc = sys_read_wwn(pp->host_dir, "port_name", &pap->PortWWN);
+
+	/* Get PortFcId */
+	rc = sa_sys_read_u32(pp->host_dir, "port_id", &pap->PortFcId);
+
+	/* Get PortType */
+	rc = sa_sys_read_line(pp->host_dir, "port_type", buf, sizeof(buf));
+	pap->PortType = get_fc_port_type_value(buf);
+
+	/* Get PortState */
+	rc = sa_sys_read_line(pp->host_dir, "port_state", buf, sizeof(buf));
+	rc = sa_enum_encode(port_states_table, buf, &pap->PortState);
+
+	/* Get PortSpeed */
+	rc = sa_sys_read_line(pp->host_dir, "speed", buf, sizeof(buf));
+	rc = sa_enum_encode(port_speeds_table, buf, &pap->PortSpeed);
+
+	/* Get PortSupportedSpeed */
+	rc = sa_sys_read_line(pp->host_dir, "supported_speed",
+				buf, sizeof(buf));
+	rc = sa_enum_encode(port_speeds_table, buf, &pap->PortSupportedSpeed);
+
+	/* Get PortMaxFrameSize */
+	rc = sa_sys_read_line(pp->host_dir, "maxframe_size", buf, sizeof(buf));
+	sscanf(buf, "%d", &pap->PortMaxFrameSize);
+
+	/* Get PortSupportedFc4Types */
+	rc = sa_sys_read_line(pp->host_dir, "supported_fc4s", buf, sizeof(buf));
+	sscanf(buf, "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x "
+		    "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x "
+		    "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x "
+		    "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
+		&data[0], &data[1], &data[2], &data[3], &data[4], &data[5],
+		&data[6], &data[7], &data[8], &data[9], &data[10], &data[11],
+		&data[12], &data[13], &data[14], &data[15], &data[16],
+		&data[17], &data[18], &data[19], &data[20], &data[21],
+		&data[22], &data[23], &data[24], &data[25], &data[26],
+		&data[27], &data[28], &data[29], &data[30], &data[31]);
+	for (i = 0; i < 32; i++)
+		pap->PortSupportedFc4Types.bits[i] = data[i];
+
+	/* Get PortActiveFc4Types */
+	rc = sa_sys_read_line(pp->host_dir, "active_fc4s", buf, sizeof(buf));
+	sscanf(buf, "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x "
+		    "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x "
+		    "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x "
+		    "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
+		&data[0], &data[1], &data[2], &data[3], &data[4], &data[5],
+		&data[6], &data[7], &data[8], &data[9], &data[10], &data[11],
+		&data[12], &data[13], &data[14], &data[15], &data[16],
+		&data[17], &data[18], &data[19], &data[20], &data[21],
+		&data[22], &data[23], &data[24], &data[25], &data[26],
+		&data[27], &data[28], &data[29], &data[30], &data[31]);
+	for (i = 0; i < 32; i++)
+		pap->PortActiveFc4Types.bits[i] = data[i];
+
+	/* Get FabricName */
+	rc = sys_read_wwn(pp->host_dir, "fabric_name", &pap->FabricName);
+
+	/* Get PortSupportedClassofService */
+	rc = sa_sys_read_line(pp->host_dir, "supported_classes",
+				buf, sizeof(buf));
+	pap->PortSupportedClassofService = *(strstr(buf, "Class") + 6) - '0';
+
+	/* Get OSDeviceName */
+	sa_strncpy_safe(pap->OSDeviceName, sizeof(pap->OSDeviceName),
+			dp->d_name, sizeof(dp->d_name));
+
+	/* Get NumberofDiscoveredPorts */
+	snprintf(buf, sizeof(buf), "%s/device", pp->host_dir);
+	sa_dir_read(buf, counting_rports, &pap->NumberofDiscoveredPorts);
+
+	/*
+	 * Add the local port structure into local port table within
+	 * the HBA structure.
+	 */
+	if (sa_table_insert(&ap->ad_ports, pp->ap_index, pp) < 0) {
+		fprintf(stderr,
+			"%s: insert of HBA %d port %d failed\n",
+			__func__, ap->ad_kern_index, pp->ap_index);
+		free(pp);
+	}
+
+	/* Create adapter name */
+	snprintf(buf, sizeof(buf), "fcoe:%s", ifname);
+	ap->ad_name = strdup(buf);
+
+	/* Get vendor_id */
+	rc = sa_sys_read_u32(hba_dir, "vendor", &hba_info.vendor_id);
+
+	/* Get device_id */
+	rc = sa_sys_read_u32(hba_dir, "device", &hba_info.device_id);
+
+	/* Get subsystem_vendor_id */
+	rc = sa_sys_read_u32(hba_dir, "subsystem_vendor",
+				&hba_info.subsystem_vendor_id);
+
+	/* Get subsystem_device_id */
+	rc = sa_sys_read_u32(hba_dir, "subsystem_device",
+				&hba_info.subsystem_device_id);
+
+	/* Get device_class */
+	rc = sa_sys_read_u32(hba_dir, "class", &hba_info.device_class);
+	hba_info.device_class = hba_info.device_class>>8;
+
+	/*
+	 * Get Hardware Information via PCI Library
+	 */
+	i = readlink(hba_dir, buf, sizeof(buf));
+	if (i < 0) {
+		printf("readlink %s failed\n", hba_dir);
+		return HBA_STATUS_ERROR;
+	}
+	buf[i] = '\0';
+	sscanf(strrchr(buf, '/') + 1, "%x:%x:%x.%x",
+		&hba_info.domain, &hba_info.bus,
+		&hba_info.dev, &hba_info.func);
+	rc = find_pci_device(&hba_info);
+	if (rc != HBA_STATUS_OK)
+		return rc;
+
+	/* Get Number of Ports */
+	atp->NumberOfPorts = hba_info.NumberOfPorts;
+
+	/* Get Manufacturer */
+	sa_strncpy_safe(atp->Manufacturer, sizeof(atp->Manufacturer),
+			hba_info.Manufacturer, sizeof(hba_info.Manufacturer));
+
+	/* Get SerialNumber */
+	sa_strncpy_safe(atp->SerialNumber, sizeof(atp->SerialNumber),
+			hba_info.SerialNumber, sizeof(hba_info.SerialNumber));
+
+	/* Get Model (TODO) */
+	sa_strncpy_safe(atp->Model, sizeof(atp->Model),
+			HBA_MODEL, sizeof(HBA_MODEL));
+
+	/* Get ModelDescription */
+	sa_strncpy_safe(atp->ModelDescription, sizeof(atp->ModelDescription),
+			hba_info.ModelDescription,
+			sizeof(hba_info.ModelDescription));
+
+	/* Get HardwareVersion */
+	sa_strncpy_safe(atp->HardwareVersion, sizeof(atp->HardwareVersion),
+			hba_info.HardwareVersion,
+			sizeof(hba_info.HardwareVersion));
+
+	/* Get OptionROMVersion (TODO) */
+	sa_strncpy_safe(atp->OptionROMVersion, sizeof(atp->OptionROMVersion),
+			HBA_ROM_VERSION, sizeof(HBA_ROM_VERSION));
+
+	/* Get FirmwareVersion (TODO) */
+	sa_strncpy_safe(atp->FirmwareVersion, sizeof(atp->FirmwareVersion),
+			HBA_FW_VERSION, sizeof(HBA_FW_VERSION));
+
+	/* Get VendorSpecificID (TODO) */
+	atp->VendorSpecificID = HBA_VENDOR_SPECIFIC_ID;
+
+	/* Get DriverVersion */
+	rc = sa_sys_read_line(hba_dir, SYSFS_MODULE_VER,
+			atp->DriverVersion, sizeof(atp->DriverVersion));
+
+	/* Get NodeSymbolicName */
+	sa_strncpy_safe(atp->NodeSymbolicName, sizeof(atp->NodeSymbolicName),
+			ap->ad_name, sizeof(atp->NodeSymbolicName));
+
+	/* Get NodeWWN - The NodeWWN is the same as
+	 *               the NodeWWN of the local port.
+	 */
+	memcpy((char *)&atp->NodeWWN, (char *)&pap->NodeWWN,
+		sizeof(pap->NodeWWN));
+
+	/* Get DriverName */
+	snprintf(drv_dir, sizeof(drv_dir), "%s" SYSFS_MODULE , hba_dir);
+	i = readlink(drv_dir, buf, sizeof(buf));
+	if (i < 0) {
+		printf("Fatal! readlink %s failed\n", drv_dir);
+		return HBA_STATUS_ERROR;
+	}
+	buf[i] = '\0';
+	if (!strstr(buf, "module")) {
+		/*
+		 * Does not find "module" in the string.
+		 * This should not happen. In this case, set
+		 * the driver name to "Unknown".
+		 */
+		driverName = "Unknown";
+	} else
+		driverName = strstr(buf, "module") + 7;
+	sa_strncpy_safe(atp->DriverName, sizeof(atp->DriverName),
+			driverName, sizeof(atp->DriverName));
+
+	/*
+	 * Give HBA to library
+	 */
+	rc = adapter_create(ap);
+	if (rc != HBA_STATUS_OK) {
+		fprintf(stderr, "%s: adapter_create failed, status=%d\n",
+			__func__, rc);
+		adapter_destroy(ap);      /* free adapter and ports */
+	}
+
+	return HBA_STATUS_OK;
+}
+
+void
+copy_wwn(HBA_WWN *dest, fc_wwn_t src)
+{
+	dest->wwn[0] = (u_char) (src >> 56);
+	dest->wwn[1] = (u_char) (src >> 48);
+	dest->wwn[2] = (u_char) (src >> 40);
+	dest->wwn[3] = (u_char) (src >> 32);
+	dest->wwn[4] = (u_char) (src >> 24);
+	dest->wwn[5] = (u_char) (src >> 16);
+	dest->wwn[6] = (u_char) (src >> 8);
+	dest->wwn[7] = (u_char) src;
+}
+
+/* Test for a non-zero WWN */
+int
+is_wwn_nonzero(HBA_WWN *wwn)
+{
+	return (wwn->wwn[0] | wwn->wwn[1] | wwn->wwn[2] | wwn->wwn[3] |
+		wwn->wwn[4] | wwn->wwn[5] | wwn->wwn[6] | wwn->wwn[7]) != 0;
+}
+
+int
+sys_read_wwn(const char *dir, const char *file, HBA_WWN *wwn)
+{
+	int rc;
+	u_int64_t val;
+
+	rc = sa_sys_read_u64(dir, file, &val);
+	if (rc == 0)
+		copy_wwn(wwn, val);
+	return rc;
+}
+
+/* Port Statistics */
+HBA_STATUS
+sysfs_get_port_stats(char *dir, HBA_PORTSTATISTICS *sp)
+{
+	int rc;
+
+	rc  = sa_sys_read_u64(dir, "seconds_since_last_reset",
+				(u_int64_t *)&sp->SecondsSinceLastReset);
+	rc |= sa_sys_read_u64(dir, "tx_frames", (u_int64_t *)&sp->TxFrames);
+	rc |= sa_sys_read_u64(dir, "tx_words", (u_int64_t *)&sp->TxWords);
+	rc |= sa_sys_read_u64(dir, "rx_frames", (u_int64_t *)&sp->RxFrames);
+	rc |= sa_sys_read_u64(dir, "rx_words", (u_int64_t *)&sp->RxWords);
+	rc |= sa_sys_read_u64(dir, "lip_count", (u_int64_t *)&sp->LIPCount);
+	rc |= sa_sys_read_u64(dir, "nos_count", (u_int64_t *)&sp->NOSCount);
+	rc |= sa_sys_read_u64(dir, "error_frames",
+				(u_int64_t *)&sp->ErrorFrames);
+	rc |= sa_sys_read_u64(dir, "dumped_frames",
+				(u_int64_t *)&sp->DumpedFrames);
+	rc |= sa_sys_read_u64(dir, "link_failure_count",
+				(u_int64_t *)&sp->LinkFailureCount);
+	rc |= sa_sys_read_u64(dir, "loss_of_sync_count",
+				(u_int64_t *)&sp->LossOfSyncCount);
+	rc |= sa_sys_read_u64(dir, "loss_of_signal_count",
+				(u_int64_t *)&sp->LossOfSignalCount);
+	rc |= sa_sys_read_u64(dir, "prim_seq_protocol_err_count",
+				(u_int64_t *)&sp->PrimitiveSeqProtocolErrCount);
+	rc |= sa_sys_read_u64(dir, "invalid_tx_word_count",
+				(u_int64_t *)&sp->InvalidTxWordCount);
+	rc |= sa_sys_read_u64(dir, "invalid_crc_count",
+				(u_int64_t *)&sp->InvalidCRCCount);
+
+	return rc;
+}
+
+/* Port FC-4 Statistics */
+HBA_STATUS
+sysfs_get_port_fc4stats(char *dir, HBA_FC4STATISTICS *fc4sp)
+{
+	int rc;
+
+	rc  = sa_sys_read_u64(dir, "fcp_input_requests",
+				(u_int64_t *)&fc4sp->InputRequests);
+	rc |= sa_sys_read_u64(dir, "fcp_output_requests",
+				(u_int64_t *)&fc4sp->OutputRequests);
+	rc |= sa_sys_read_u64(dir, "fcp_control_requests",
+				(u_int64_t *)&fc4sp->ControlRequests);
+	rc |= sa_sys_read_u64(dir, "fcp_input_megabytes",
+				(u_int64_t *)&fc4sp->InputMegabytes);
+	rc |= sa_sys_read_u64(dir, "fcp_output_megabytes",
+				(u_int64_t *)&fc4sp->OutputMegabytes);
+
+	return rc;
+}
+/*
+ * Open device and read adapter info if available.
+ */
+void
+adapter_init(void)
+{
+	sa_dir_read(SYSFS_HOST_DIR, sysfs_scan, NULL);
+}
+
+void
+adapter_shutdown(void)
+{
+}
+
+HBA_STATUS
+get_port_statistics(HBA_HANDLE handle, HBA_UINT32 port, HBA_PORTSTATISTICS *sp)
+{
+	struct port_info *pp;
+	char dir[80];
+	int rc;
+
+	memset(sp, 0xff, sizeof(*sp)); /* unsupported statistics give -1 */
+	pp = adapter_get_port(handle, port);
+	if (pp == NULL) {
+		fprintf(stderr, "%s: lookup failed. handle 0x%x port 0x%x\n",
+			__func__, handle, port);
+		return HBA_STATUS_ERROR;
+	}
+
+	snprintf(dir, sizeof(dir), "%s/statistics", pp->host_dir);
+	rc = sysfs_get_port_stats(dir, sp);
+	if (rc != 0) {
+		fprintf(stderr, "%s: sysfs_get_port_stats() failed,"
+			" hba index=%d port index=%d, -rc=0x%x\n",
+			__func__, pp->ap_adapt->ad_kern_index,
+			pp->ap_index, -rc);
+		return HBA_STATUS_ERROR;
+	}
+	return HBA_STATUS_OK;
+}
+
+/*
+ * Get FC4 statistics.
+ */
+HBA_STATUS
+get_port_fc4_statistics(HBA_HANDLE handle, HBA_WWN wwn,
+		       HBA_UINT8 fc4_type, HBA_FC4STATISTICS *sp)
+{
+	struct port_info *pp;
+	char dir[80];
+	int count;
+	int rc;
+
+	memset(sp, 0xff, sizeof(*sp)); /* unsupported statistics give -1 */
+
+	pp = adapter_get_port_by_wwn(handle, wwn, &count);
+	if (count > 1)
+		return HBA_STATUS_ERROR_AMBIGUOUS_WWN;
+	else if (pp == NULL)
+		return HBA_STATUS_ERROR_ILLEGAL_WWN;
+
+	snprintf(dir, sizeof(dir), "%s/statistics", pp->host_dir);
+	rc = sysfs_get_port_fc4stats(dir, sp);
+	if (rc != 0) {
+		fprintf(stderr, "%s: sysfs_get_port_fc4stats() failed,"
+			" hba index=%d port index=%d, -rc=0x%x\n",
+			__func__, pp->ap_adapt->ad_kern_index,
+			pp->ap_index, -rc);
+		return HBA_STATUS_ERROR;
+	}
+	return HBA_STATUS_OK;
+}
+
diff --git a/src/pci.c b/src/pci.c
new file mode 100644
index 0000000..94032dd
--- /dev/null
+++ b/src/pci.c
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 2008, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU Lesser General Public License,
+ * version 2.1, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include "utils.h"
+#include "adapt_impl.h"
+#include <linux/pci_regs.h>
+#include <pciaccess.h>
+#include <byteswap.h>
+
+static void
+get_device_serial_number(struct pci_device *dev, struct hba_info *hba_info)
+{
+	pciaddr_t offset;
+	u_int32_t pcie_cap_header;
+	u_int16_t pcie_cap_id;
+	u_int16_t status;
+	u_int8_t cap_ptr;
+	u_int32_t dword_low = 0;
+	u_int32_t dword_high = 0;
+	int rc;
+
+	/*
+	 * Read the Status Register in the PCIe configuration
+	 * header space to see if the PCI Capability List is
+	 * supported by this device.
+	 */
+	rc = pci_device_cfg_read_u16(dev, &status, PCI_STATUS);
+	if (rc) {
+		fprintf(stderr, "Failed reading PCI Status Register\n");
+		return;
+	}
+	if (!(status & PCI_STATUS_CAP_LIST)) {
+		printf("PCI capabilities are not supported\n");
+		return;
+	}
+
+	/*
+	 * Read the offset (cap_ptr) of first entry in the capability list in
+	 * the PCI configuration space.
+	 */
+	rc = pci_device_cfg_read_u8(dev, &cap_ptr, PCI_CAPABILITY_LIST);
+	if (rc) {
+		fprintf(stderr,
+			"Failed reading PCI Capability List Register\n");
+		return;
+	}
+	offset = cap_ptr;
+
+	/* Search for the PCIe capability */
+	while (offset) {
+		u_int8_t cap_id;
+		u_int8_t next_cap;
+
+		rc = pci_device_cfg_read_u8(dev, &cap_id,
+					    offset + PCI_CAP_LIST_ID);
+		if (rc) {
+			fprintf(stderr,
+				"Failed reading capability ID at 0x%lx\n",
+				offset + PCI_CAP_LIST_ID);
+			return;
+		}
+
+		if (cap_id != PCI_CAP_ID_EXP) {
+			rc = pci_device_cfg_read_u8(dev, &next_cap,
+						    offset + PCI_CAP_LIST_NEXT);
+			if (rc) {
+				fprintf(stderr,
+					"Failed reading next capability "
+					"offset at 0x%lx\n",
+					offset + PCI_CAP_LIST_NEXT);
+				return;
+			}
+			offset = (pciaddr_t)next_cap;
+			continue;
+		}
+
+		/*
+		 * PCIe Capability Structure exists!
+		 */
+
+		/*
+		 * The first PCIe extended capability is located at
+		 * offset 0x100 in the device configuration space.
+		 */
+		offset = 0x100;
+
+		do {
+			rc = pci_device_cfg_read_u32(dev, &pcie_cap_header,
+						     offset);
+			if (rc) {
+				fprintf(stderr,
+					"Failed reading PCIe config header\n");
+				return;
+			}
+
+			/* Get the PCIe Extended Capability ID */
+			pcie_cap_id = pcie_cap_header & 0xffff;
+
+			if (pcie_cap_id != PCI_EXT_CAP_ID_DSN) {
+				/* Get the offset of the next capability */
+				offset = (pciaddr_t)pcie_cap_header >> 20;
+				continue;
+			}
+
+			/*
+			 * Found the serial number register!
+			 */
+
+			rc = pci_device_cfg_read_u32(dev,
+						     &dword_low, offset + 4);
+			rc = pci_device_cfg_read_u32(dev,
+						     &dword_high, offset + 8);
+			snprintf(hba_info->SerialNumber,
+				 sizeof(hba_info->SerialNumber),
+				"%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x\n",
+				dword_low & 0xff, (dword_low >> 8) & 0xff,
+				(dword_low >> 16) & 0xff, dword_low >> 24,
+				dword_high & 0xff, (dword_high >> 8) & 0xff,
+				(dword_high >> 16) & 0xff, dword_high >> 24);
+			break;
+		} while (offset);
+		break;
+	}
+}
+
+static void
+get_pci_device_info(struct pci_device *dev, struct hba_info *hba_info)
+{
+	const char *name;
+	u_int16_t class;
+	u_int8_t revision;
+	u_int8_t hdr_type;
+	char *unknown = "Unknown";
+
+	hba_info->vendor_id = dev->vendor_id;
+	hba_info->device_id = dev->device_id;
+	hba_info->subsystem_vendor_id = dev->subvendor_id;
+	hba_info->subsystem_device_id = dev->subdevice_id;
+
+	name = pci_device_get_vendor_name(dev);
+	if (!name)
+		name = unknown;
+	sa_strncpy_safe(hba_info->Manufacturer,
+			sizeof(hba_info->Manufacturer),
+			name, sizeof(hba_info->Manufacturer));
+
+	name = pci_device_get_device_name(dev);
+	if (!name)
+		name = unknown;
+	sa_strncpy_safe(hba_info->ModelDescription,
+			sizeof(hba_info->ModelDescription),
+			name, sizeof(hba_info->ModelDescription));
+
+	/*
+	 * Reading device class and revision from PCIe
+	 * configuration header space.
+	 */
+	pci_device_cfg_read_u16(dev, &class, PCI_CLASS_DEVICE);
+	hba_info->device_class = class;
+
+	pci_device_cfg_read_u8(dev, &revision, PCI_REVISION_ID);
+	snprintf(hba_info->HardwareVersion,
+		 sizeof(hba_info->HardwareVersion),
+		 "%02x", revision);
+
+	/*
+	 * Determine if the HBA is a single-function
+	 * or multi-function adapter.
+	 */
+	pci_device_cfg_read_u8(dev, &hdr_type, PCI_HEADER_TYPE);
+	if (hdr_type == 0x80)
+		hba_info->NumberOfPorts = 2;
+	else
+		hba_info->NumberOfPorts = 1;
+
+	/*
+	 * Searching for serial number in PCIe extended
+	 * capabilities space
+	 */
+	get_device_serial_number(dev, hba_info);
+}
+
+HBA_STATUS
+find_pci_device(struct hba_info *hba_info)
+{
+	struct pci_device_iterator *iterator;
+	struct pci_device *dev;
+	struct pci_slot_match match;
+
+	int rc;
+
+	rc = pci_system_init();
+	if (rc) {
+		fprintf(stderr, "pci_system_init failed\n");
+		return HBA_STATUS_ERROR;
+	}
+
+	match.domain = hba_info->domain;
+	match.bus = hba_info->bus;
+	match.dev = hba_info->dev;
+	match.func = hba_info->func;
+
+	iterator = pci_slot_match_iterator_create(&match);
+
+	for (;;) {
+		dev = pci_device_next(iterator);
+		if (!dev)
+			break;
+		get_pci_device_info(dev, hba_info);
+	}
+
+	pci_system_cleanup();
+	return HBA_STATUS_OK;
+}
+
diff --git a/src/rport.c b/src/rport.c
new file mode 100644
index 0000000..7b72872
--- /dev/null
+++ b/src/rport.c
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2008, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU Lesser General Public License,
+ * version 2.1, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include "utils.h"
+#include "api_lib.h"
+#include "adapt_impl.h"
+
+static int sys_read_port_state(const char *, const char *, u_int32_t *);
+static int sys_read_classes(const char *, const char *, u_int32_t *);
+
+static struct sa_table rports_table;          /* table of discovered ports */
+
+/*
+ * Handle a single remote port from the /sys directory entry.
+ * The return value is 0 unless an error is detected which should stop the
+ * directory read.
+ */
+static int
+sysfs_get_rport(struct dirent *dp, void *arg)
+{
+	struct port_info *rp;
+	HBA_PORTATTRIBUTES *rpa;
+	int rc;
+	u_int32_t hba;
+	u_int32_t port;
+	u_int32_t rp_index;
+	char *rport_dir;
+	char buf[256];
+
+	/*
+	 * Parse name into bus number, channel number, and remote port number.
+	 */
+	hba = ~0;
+	port = ~0;
+	rp_index = ~0;
+	rc = sscanf(dp->d_name, SYSFS_RPORT_DIR, &hba, &port, &rp_index);
+	if (rc != 3) {
+		fprintf(stderr,
+			"%s: remote port %s didn't parse."
+			" rc %d h 0x%x p 0x%x rp 0x%x\n", __func__,
+			dp->d_name, rc, hba, port, rp_index);
+		return 0;
+	}
+
+	/*
+	 * Allocate a remote port.
+	 */
+	rp = malloc(sizeof(*rp));
+	if (rp == NULL) {
+		fprintf(stderr, "%s: malloc for remote port %s failed,"
+			" errno=0x%x\n", __func__, dp->d_name, errno);
+		return ENOMEM;
+	}
+	memset(rp, 0, sizeof(*rp));
+	rp->ap_kern_hba = hba;
+	rp->ap_index = port;
+	rp->ap_disc_index = rp_index;
+	rpa = &rp->ap_attr;
+
+	snprintf(rpa->OSDeviceName, sizeof(rpa->OSDeviceName), "%s/%s",
+		SYSFS_RPORT_ROOT, dp->d_name);
+	rport_dir = rpa->OSDeviceName;
+	rc = 0;
+	rc |= sys_read_wwn(rport_dir, "node_name", &rpa->NodeWWN);
+	rc |= sys_read_wwn(rport_dir, "port_name", &rpa->PortWWN);
+	rc |= sa_sys_read_u32(rport_dir, "port_id", &rpa->PortFcId);
+	rc |= sa_sys_read_u32(rport_dir, "scsi_target_id", &rp->ap_scsi_target);
+	rc |= sa_sys_read_line(rport_dir, "maxframe_size", buf, sizeof(buf));
+	sscanf(buf, "%d", &rpa->PortMaxFrameSize);
+	rc |= sys_read_port_state(rport_dir, "port_state", &rpa->PortState);
+	rc |= sys_read_classes(rport_dir, "supported_classes",
+				   &rpa->PortSupportedClassofService);
+	if (rc != 0 || sa_table_append(&rports_table, rp) < 0) {
+		if (rc != 0)
+			fprintf(stderr,
+				"%s: errors (%x) from /sys reads in %s\n",
+				__func__, rc, dp->d_name);
+		else
+			fprintf(stderr,
+				"%s: sa_table_append error on rport %s\n",
+				__func__, dp->d_name);
+		free(rp);
+	}
+	return 0;
+}
+
+/*
+ * Get remote port information from /sys.
+ */
+static void
+sysfs_find_rports(void)
+{
+	sa_dir_read(SYSFS_RPORT_ROOT, sysfs_get_rport, NULL);
+}
+
+/*
+ * Read port state as formatted by scsi_transport_fc.c in the linux kernel.
+ */
+static int
+sys_read_port_state(const char *dir, const char *file, u_int32_t *statep)
+{
+	char buf[256];
+	int rc;
+
+	rc = sa_sys_read_line(dir, file, buf, sizeof(buf));
+	if (rc == 0) {
+		rc = sa_enum_encode(port_states_table, buf, statep);
+		if (rc != 0)
+			fprintf(stderr,
+				"%s: parse error. file %s/%s line '%s'\n",
+				__func__, dir, file, buf);
+	}
+	return rc;
+}
+
+/*
+ * Read class list as formatted by scsi_transport_fc.c in the linux kernel.
+ * Format is expected to be "Class 3[, Class 4]..."
+ * Actually accepts "[Class ]3[,[ ][Class ]4]..." (i.e., "Class" and spaces
+ * are optional).
+ */
+static int
+sys_read_classes(const char *dir, const char *file, u_int32_t *classp)
+{
+	char buf[256];
+	int rc;
+	u_int32_t val;
+	char *cp;
+	char *ep;
+
+	*classp = 0;
+	rc = sa_sys_read_line(dir, file, buf, sizeof(buf));
+	if (rc == 0 && strstr(buf, "unspecified") == NULL) {
+		for (cp = buf; *cp != '\0'; cp = ep) {
+			if (strncmp(cp, "Class ", 6) == 0)
+				cp += 6;
+			val = strtoul(cp, &ep, 10);
+			*classp |= 1 << val;
+			if (*ep == '\0')
+				break;
+			if (*ep == ',') {
+				ep++;
+				if (*ep == ' ')
+					ep++;
+			} else {
+				fprintf(stderr, "%s: parse error. file %s/%s "
+				       "line '%s' ep '%c'\n", __func__,
+					dir, file, buf, *ep);
+				rc = -1;
+				break;
+			}
+		}
+	}
+	return rc;
+}
+
+/*
+ * Get all discovered ports for a particular port using /sys.
+ */
+void
+get_rport_info(struct port_info *pp)
+{
+	struct port_info *rp;
+	int rp_count = 0;
+	int ri;
+
+	if (rports_table.st_size == 0)
+		sysfs_find_rports();
+
+	for (ri = 0; ri < rports_table.st_size; ri++) {
+		rp = sa_table_lookup(&rports_table, ri);
+		if (rp != NULL) {
+			if (rp->ap_kern_hba == pp->ap_kern_hba &&
+			    rp->ap_index == pp->ap_index &&
+			    rp->ap_adapt == NULL) {
+				rp->ap_adapt = pp->ap_adapt;
+				if (sa_table_lookup(&pp->ap_rports,
+						    rp->ap_disc_index)) {
+					fprintf(stderr,
+						"%s: discovered port exists. "
+					       "hba %x port %x rport %x\n",
+					       __func__, pp->ap_kern_hba,
+					       pp->ap_index, rp->ap_disc_index);
+				}
+				sa_table_insert(&pp->ap_rports,
+						rp->ap_disc_index, rp);
+			}
+			rp_count++;
+		}
+	}
+}
+
diff --git a/src/scsi.c b/src/scsi.c
new file mode 100644
index 0000000..c04d410
--- /dev/null
+++ b/src/scsi.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2008, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU Lesser General Public License,
+ * version 2.1, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include "utils.h"
+#include "api_lib.h"
+#include "adapt_impl.h"
+#include "bind_impl.h"
+#include "fc_scsi.h"
+
+/*
+ * Inquiry V1.
+ */
+HBA_STATUS
+scsi_inquiry_v1(HBA_HANDLE handle, HBA_WWN disc_wwpn, HBA_UINT64 fc_lun,
+		    HBA_UINT8 evpd, HBA_UINT32 page_code, void *resp,
+		    HBA_UINT32 resp_len, void *sense, HBA_UINT32 sense_len)
+{
+	struct port_info *pp;
+	char sg_name[50];
+	HBA_UINT8 stat;
+	HBA_STATUS status;
+
+	/*
+	 * Find port.
+	 */
+	pp = adapter_get_port(handle, 0);
+	if (pp == NULL)
+		return HBA_STATUS_ERROR_INVALID_HANDLE;
+
+	if (get_binding_sg_name(
+	    pp, disc_wwpn, fc_lun, sg_name, sizeof(sg_name)) != 0)
+		return HBA_STATUS_ERROR_TARGET_LUN;
+
+	status = sg_issue_inquiry(sg_name, evpd ? SCSI_INQF_EVPD : 0, page_code,
+				resp, &resp_len, &stat, sense, &sense_len);
+	if (status == HBA_STATUS_OK && stat == SCSI_ST_CHECK)
+		status = HBA_STATUS_SCSI_CHECK_CONDITION;
+
+	return status;
+}
+
+/*
+ * Inquiry V2.
+ */
+HBA_STATUS
+scsi_inquiry_v2(HBA_HANDLE handle, HBA_WWN wwpn, HBA_WWN disc_wwpn,
+		    HBA_UINT64 fc_lun, HBA_UINT8 cdb_byte1,
+		    HBA_UINT8 cdb_byte2, void *resp, HBA_UINT32 *resp_lenp,
+		    HBA_UINT8 *statp, void *sense, HBA_UINT32 *sense_lenp)
+{
+	struct port_info *pp;
+	char sg_name[50];
+
+	/*
+	 * Find port.
+	 */
+	pp = adapter_get_port_by_wwn(handle, wwpn, NULL);
+	if (pp == NULL)
+		return HBA_STATUS_ERROR_ILLEGAL_WWN;
+
+	if (get_binding_sg_name(
+	    pp, disc_wwpn, fc_lun, sg_name, sizeof(sg_name)) != 0)
+		return HBA_STATUS_ERROR_TARGET_LUN;
+
+	return sg_issue_inquiry(sg_name, cdb_byte1, cdb_byte2,
+			       resp, resp_lenp, statp, sense, sense_lenp);
+}
+
+/*
+ * Read capacity V1.
+ */
+HBA_STATUS
+scsi_read_capacity_v1(HBA_HANDLE handle, HBA_WWN disc_wwpn,
+			  HBA_UINT64 fc_lun, void *resp,
+			  HBA_UINT32 resp_len, void *sense,
+			  HBA_UINT32 sense_len)
+{
+	struct port_info *pp;
+	char sg_name[50];
+	HBA_UINT8 stat;
+	HBA_STATUS status;
+
+	/*
+	 * Find port.
+	 */
+	pp = adapter_get_port(handle, 0);
+	if (pp == NULL)
+		return HBA_STATUS_ERROR_INVALID_HANDLE;
+
+	if (get_binding_sg_name(
+	    pp, disc_wwpn, fc_lun, sg_name, sizeof(sg_name)) != 0)
+		return HBA_STATUS_ERROR_TARGET_LUN;
+
+	status = sg_issue_read_capacity(sg_name, resp, &resp_len,
+				 &stat, sense, &sense_len);
+	if (status == HBA_STATUS_OK && stat == SCSI_ST_CHECK)
+		status = HBA_STATUS_SCSI_CHECK_CONDITION;
+
+	return status;
+}
+
+/*
+ * Read capacity V2.
+ */
+HBA_STATUS
+scsi_read_capacity_v2(HBA_HANDLE handle, HBA_WWN wwpn,
+			  HBA_WWN disc_wwpn, HBA_UINT64 fc_lun,
+			  void *resp, HBA_UINT32 *resp_lenp,
+			  HBA_UINT8 *statp, void *sense,
+			  HBA_UINT32 *sense_lenp)
+{
+	struct port_info *pp;
+	char sg_name[50];
+
+	/*
+	 * Find port.
+	 */
+	pp = adapter_get_port_by_wwn(handle, wwpn, NULL);
+	if (pp == NULL)
+		return HBA_STATUS_ERROR_ILLEGAL_WWN;
+
+	if (get_binding_sg_name(
+	    pp, disc_wwpn, fc_lun, sg_name, sizeof(sg_name)) != 0)
+		return HBA_STATUS_ERROR_TARGET_LUN;
+
+	return sg_issue_read_capacity(sg_name, resp, resp_lenp,
+				statp, sense, sense_lenp);
+}
+
+/*
+ * Report LUNS V1.
+ */
+HBA_STATUS
+scsi_report_luns_v1(HBA_HANDLE handle, HBA_WWN disc_wwpn,
+			void *resp, HBA_UINT32 resp_len,
+			void *sense, HBA_UINT32 sense_len)
+{
+	struct port_info *pp;
+	char sg_name[50];
+	HBA_UINT8 stat;
+	HBA_STATUS status;
+
+	/*
+	 * Find port.
+	 */
+	pp = adapter_get_port(handle, 0);
+	if (pp == NULL)
+		return HBA_STATUS_ERROR_INVALID_HANDLE;
+
+	if (get_binding_sg_name(
+	    pp, disc_wwpn, 0, sg_name, sizeof(sg_name)) != 0)
+		return HBA_STATUS_ERROR_TARGET_PORT_WWN;
+
+	status = sg_issue_report_luns(sg_name, resp, &resp_len,
+				    &stat, sense, &sense_len);
+	if (status == HBA_STATUS_OK && stat == SCSI_ST_CHECK)
+		status = HBA_STATUS_SCSI_CHECK_CONDITION;
+
+	return status;
+}
+
+/*
+ * Report LUNS V2.
+ */
+HBA_STATUS
+scsi_report_luns_v2(HBA_HANDLE handle, HBA_WWN wwpn,
+			HBA_WWN disc_wwpn, void *resp,
+			HBA_UINT32 *resp_lenp, HBA_UINT8 *statp,
+			void *sense, HBA_UINT32 *sense_lenp)
+{
+	struct port_info *pp;
+	char sg_name[50];
+
+	/*
+	 * Find port.
+	 */
+	pp = adapter_get_port_by_wwn(handle, wwpn, NULL);
+	if (pp == NULL)
+		return HBA_STATUS_ERROR_ILLEGAL_WWN;
+
+	if (get_binding_sg_name(
+	    pp, disc_wwpn, 0, sg_name, sizeof(sg_name)) != 0)
+		return HBA_STATUS_ERROR_TARGET_PORT_WWN;
+
+	return sg_issue_report_luns(sg_name, resp, resp_lenp,
+				  statp, sense, sense_lenp);
+}
+
diff --git a/src/sg.c b/src/sg.c
new file mode 100644
index 0000000..f324b9a
--- /dev/null
+++ b/src/sg.c
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) 2008, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU Lesser General Public License,
+ * version 2.1, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <sys/ioctl.h>
+#include "utils.h"
+#include "api_lib.h"
+#include "adapt_impl.h"
+#include "fc_scsi.h"
+
+/*
+ * Perform INQUIRY of SCSI-generic device.
+ */
+HBA_STATUS
+sg_issue_inquiry(const char *file, HBA_UINT8 cdb_byte1,
+	       HBA_UINT8 cdb_byte2, void *buf, HBA_UINT32 *lenp,
+	       HBA_UINT8 *statp, void *sense, HBA_UINT32 *sense_lenp)
+{
+	struct sg_io_hdr hdr;
+	struct scsi_inquiry cmd;
+	size_t len;
+	HBA_UINT32 slen;
+	int fd;
+	int rc;
+
+	len = *lenp;
+	slen = *sense_lenp;
+	if (slen > 255)
+		slen = 255;   /* must fit in an 8-bit field */
+	if (len > 255)
+		len = 255;    /* sometimes must fit in 8-byte field */
+	*lenp = 0;
+	*statp = 0;
+	fd = open(file, O_RDWR);
+	if (fd < 0) {
+		fprintf(stderr, "%s: open of %s failed, errno=0x%x\n",
+			__func__, file, errno);
+		return HBA_STATUS_ERROR;
+	}
+	memset(&hdr, 0, sizeof(hdr));
+	memset(&cmd, 0, sizeof(cmd));
+	memset(buf, 0, len);
+
+	cmd.in_op = SCSI_OP_INQUIRY;
+	cmd.in_flags = cdb_byte1;
+	cmd.in_page_code = cdb_byte2;
+	ua_net16_put(&cmd.in_alloc_len, len); /* field may actually be 8 bits */
+
+	hdr.interface_id = 'S';
+	hdr.dxfer_direction = SG_DXFER_FROM_DEV;
+	hdr.cmd_len = sizeof(cmd);
+	hdr.mx_sb_len = slen;
+	hdr.dxfer_len = len;
+	hdr.dxferp = (unsigned char *) buf;
+	hdr.cmdp = (unsigned char *) &cmd;
+	hdr.sbp = (unsigned char *) sense;
+	hdr.timeout = 3000;                     /* mS to wait for result */
+
+	rc = ioctl(fd, SG_IO, &hdr);
+	if (rc < 0) {
+		rc = errno;
+		fprintf(stderr, "%s: SG_IO error. file %s, errno=0x%x\n",
+			__func__, file, errno);
+		return HBA_STATUS_ERROR;
+	}
+	close(fd);
+	*lenp = len - hdr.resid;
+	*sense_lenp = hdr.sb_len_wr;
+	*statp = hdr.status;
+	return HBA_STATUS_OK;
+}
+
+static inline unsigned int
+sg_get_id_type(struct scsi_inquiry_desc *dp)
+{
+	return dp->id_type_flags & SCSI_INQT_TYPE_MASK;
+}
+
+/*
+ * Get device ID information for HBA-API.
+ * See the spec.  We get the "best" information and leave the rest.
+ * The buffer is left empty if nothing is gotten.
+ */
+void
+sg_get_dev_id(const char *name, char *buf, size_t result_len)
+{
+	struct scsi_inquiry_dev_id *idp;
+	struct scsi_inquiry_desc *dp;
+	struct scsi_inquiry_desc *best = NULL;
+	char sense[252];
+	HBA_UINT32 len;
+	HBA_UINT32 slen;
+	u_char scsi_stat;
+	size_t rlen;
+	size_t dlen;
+	unsigned int type;
+
+	memset(buf, 0, result_len);
+	len = result_len;
+	slen = sizeof(sense);
+	idp = (struct scsi_inquiry_dev_id *) buf;
+	sg_issue_inquiry(name, SCSI_INQF_EVPD, SCSI_INQP_DEV_ID,
+			buf, &len, &scsi_stat, sense, &slen);
+	if (len < sizeof(*idp))
+		return;
+	if (idp->is_page_code != SCSI_INQP_DEV_ID)
+		return;
+	len -= sizeof(*idp);
+	rlen = net16_get(&idp->is_page_len);
+	if (rlen > len)
+		rlen = len;
+	dp = (struct scsi_inquiry_desc *) (idp + 1);
+	for (; rlen >= sizeof(*dp);
+	     rlen -= dlen,
+	     dp = (struct scsi_inquiry_desc *) ((char *) dp + dlen)) {
+		dlen = dp->id_designator_len + sizeof(*dp) -
+		       sizeof(dp->id_designator[0]);
+		if (dlen > rlen)
+			break;
+		type = sg_get_id_type(dp);
+		if (type > SCSI_DTYPE_NAA)
+			continue;
+		if (best == NULL)
+			best = dp;
+		else if (type == sg_get_id_type(best) &&
+			   (dp->id_designator_len < best->id_designator_len ||
+			   (dp->id_designator_len == best->id_designator_len &&
+			   memcmp(dp->id_designator, best->id_designator,
+			   best->id_designator_len) < 0))) {
+			best = dp;
+		} else if (type > sg_get_id_type(best))
+			best = dp;
+	}
+	if (best) {
+		dp = best;
+		dlen = dp->id_designator_len + sizeof(*dp) -
+			sizeof(dp->id_designator[0]);
+		if (dlen > result_len)
+			dlen = 0;                       /* can't happen */
+		else
+			memmove(buf, dp, dlen);         /* areas may overlap */
+		memset(buf +  dlen, 0, result_len - dlen);
+	}
+}
+
+/*
+ * Read Capacity for HBA-API.
+ */
+HBA_STATUS
+sg_issue_read_capacity(const char *file, void *resp, HBA_UINT32 *resp_lenp,
+		HBA_UINT8 *statp, void *sense, HBA_UINT32 *sense_lenp)
+{
+	struct sg_io_hdr hdr;
+	struct scsi_rcap10 cmd;
+	size_t len;
+	int fd;
+	int rc;
+
+	len = *resp_lenp;
+	*resp_lenp = 0;
+	fd = open(file, O_RDWR);
+	if (fd < 0) {
+		fprintf(stderr, "%s: open of %s failed, errno=0x%x\n",
+			__func__, file, errno);
+		return errno;
+	}
+	memset(&hdr, 0, sizeof(hdr));
+	memset(&cmd, 0, sizeof(cmd));
+
+	cmd.rc_op = SCSI_OP_READ_CAP10;
+
+	hdr.interface_id = 'S';
+	hdr.dxfer_direction = SG_DXFER_FROM_DEV;
+	hdr.cmd_len = sizeof(cmd);
+	hdr.mx_sb_len = *sense_lenp;
+	hdr.dxfer_len = len;
+	hdr.dxferp = (unsigned char *) resp;
+	hdr.cmdp = (unsigned char *) &cmd;
+	hdr.sbp = (unsigned char *) sense;
+	hdr.timeout = UINT_MAX;
+	hdr.timeout = 3000;                     /* mS to wait for result */
+
+	rc = ioctl(fd, SG_IO, &hdr);
+	if (rc < 0) {
+		rc = errno;
+		fprintf(stderr, "%s: SG_IO error. file %s, errno=0x%x\n",
+			__func__, file, errno);
+		return HBA_STATUS_ERROR;
+	}
+	close(fd);
+	*resp_lenp = len - hdr.resid;
+	*sense_lenp = hdr.sb_len_wr;
+	*statp = hdr.status;
+	return HBA_STATUS_OK;
+}
+
+/*
+ * Report LUNs for HBA-API.
+ */
+HBA_STATUS
+sg_issue_report_luns(const char *file, void *resp, HBA_UINT32 *resp_lenp,
+		   HBA_UINT8 *statp, void *sense, HBA_UINT32 *sense_lenp)
+{
+	struct sg_io_hdr hdr;
+	struct scsi_report_luns cmd;
+	size_t len;
+	int fd;
+	int rc;
+
+	len = *resp_lenp;
+	*resp_lenp = 0;
+	fd = open(file, O_RDWR);
+	if (fd < 0) {
+		fprintf(stderr, "%s: open of %s failed, errno=0x%x\n",
+			__func__, file, errno);
+		return errno;
+	}
+	memset(&hdr, 0, sizeof(hdr));
+	memset(&cmd, 0, sizeof(cmd));
+
+	cmd.rl_op = SCSI_OP_REPORT_LUNS;
+	ua_net32_put(&cmd.rl_alloc_len, len);
+
+	hdr.interface_id = 'S';
+	hdr.dxfer_direction = SG_DXFER_FROM_DEV;
+	hdr.cmd_len = sizeof(cmd);
+	hdr.mx_sb_len = *sense_lenp;
+	hdr.dxfer_len = len;
+	hdr.dxferp = (unsigned char *) resp;
+	hdr.cmdp = (unsigned char *) &cmd;
+	hdr.sbp = (unsigned char *) sense;
+	hdr.timeout = UINT_MAX;
+	hdr.timeout = 3000;                     /* mS to wait for result */
+
+	rc = ioctl(fd, SG_IO, &hdr);
+	if (rc < 0) {
+		rc = errno;
+		fprintf(stderr, "%s: SG_IO error. file %s, errno=0x%x\n",
+			__func__, file, errno);
+		return HBA_STATUS_ERROR;
+	}
+	close(fd);
+	*resp_lenp = len - hdr.resid;
+	*sense_lenp = hdr.sb_len_wr;
+	*statp = hdr.status;
+	return HBA_STATUS_OK;
+}
+
diff --git a/src/utils.c b/src/utils.c
new file mode 100644
index 0000000..cc5c655
--- /dev/null
+++ b/src/utils.c
@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 2008, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU Lesser General Public License,
+ * version 2.1, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include "utils.h"
+
+/*
+ * Read a line from the specified file in the specified directory
+ * into the buffer.  The file is opened and closed.
+ * Any trailing white space is trimmed off.
+ * This is useful for accessing /sys files.
+ * Returns 0 or an error number.
+ */
+int
+sa_sys_read_line(const char *dir, const char *file, char *buf, size_t len)
+{
+	FILE *fp;
+	char file_name[256];
+	char *cp;
+	int rc = 0;
+
+	snprintf(file_name, sizeof(file_name), "%s/%s", dir, file);
+	fp = fopen(file_name, "r");
+	if (fp == NULL)
+		rc = -1;
+	else {
+		cp = fgets(buf, len, fp);
+		if (cp == NULL) {
+			fprintf(stderr,
+				"%s: read error or empty file %s,"
+				" errno=0x%x\n", __func__,
+				file_name, errno);
+			rc = -1;
+		} else {
+
+			/*
+			 * Trim off trailing newline or other white space.
+			 */
+			cp = buf + strlen(buf);
+			while (--cp >= buf && isspace(*cp))
+				*cp = '\0';
+		}
+		fclose(fp);
+	}
+	return rc;
+}
+
+/*
+ * Write a string to the specified file in the specified directory.
+ * The file is opened and closed.
+ * The string has a new-line appended to it.
+ * This is useful for accessing /sys files.
+ * Returns 0 or an error number.
+ */
+int
+sa_sys_write_line(const char *dir, const char *file, const char *string)
+{
+	FILE *fp;
+	char file_name[256];
+	int rc = 0;
+
+	snprintf(file_name, sizeof(file_name), "%s/%s", dir, file);
+	fp = fopen(file_name, "w");
+	if (fp == NULL) {
+		fprintf(stderr, "%s: fopen of %s failed, errno=0x%x\n",
+			__func__, file_name, errno);
+		rc = -1;
+	} else {
+		rc = fprintf(fp, "%s\n", string);
+		if (rc < 0)
+			fprintf(stderr,
+				"%s: write to %s of %s failed, errno=0x%x\n",
+				__func__, file_name, string, errno);
+		fclose(fp);
+	}
+	return rc;
+}
+
+int
+sa_sys_read_u32(const char *dir, const char *file, u_int32_t *vp)
+{
+	char buf[256];
+	int rc;
+	u_int32_t val;
+	char *endptr;
+
+	rc = sa_sys_read_line(dir, file, buf, sizeof(buf));
+	if (rc == 0) {
+		val = strtoul(buf, &endptr, 0);
+		if (*endptr != '\0') {
+			fprintf(stderr,
+				"%s: parse error. file %s/%s line '%s'\n",
+				__func__, dir, file, buf);
+			rc = -1;
+		} else
+			*vp = val;
+	}
+	return rc;
+}
+
+int
+sa_sys_read_u64(const char *dir, const char *file, u_int64_t *vp)
+{
+	char buf[256];
+	int rc;
+	u_int64_t val;
+	char *endptr;
+
+	rc = sa_sys_read_line(dir, file, buf, sizeof(buf));
+	if (rc == 0) {
+		val = strtoull(buf, &endptr, 0);
+		if (*endptr != '\0') {
+			fprintf(stderr,
+				"%s: parse error. file %s/%s line '%s'\n",
+				__func__, dir, file, buf);
+			rc = -1;
+		} else
+			*vp = val;
+	}
+	return rc;
+}
+
+/*
+ * Make a printable NUL-terminated copy of the string.
+ * The source buffer might not be NUL-terminated.
+ */
+char *
+sa_strncpy_safe(char *dest, size_t len, const char *src, size_t src_len)
+{
+	char *dp = dest;
+	const char *sp = src;
+
+	while (len-- > 1 && src_len-- > 0 && *sp != '\0') {
+		*dp++ = isprint(*sp) ? *sp : (isspace(*sp) ? ' ' : '.');
+		sp++;
+	}
+	*dp = '\0';
+
+	/*
+	 * Take off trailing blanks.
+	 */
+	while (--dp >= dest && isspace(*dp))
+		*dp = '\0';
+
+	return dest;
+}
+
+/** sa_enum_encode(tp, name, valp)
+ *
+ * @param tp pointer to table of names and values, struct sa_nameval.
+ * @param name string to be encoded into a value
+ * @returns zero on success, non-zero if no matching string found.
+ */
+int
+sa_enum_encode(const struct sa_nameval *tp, const char *name, u_int32_t *valp)
+{
+	for (; tp->nv_name != NULL; tp++) {
+		if (strcasecmp(tp->nv_name, name) == 0) {
+			*valp = tp->nv_val;
+			return 0;
+		}
+	}
+	return -1;
+}
+
+/** sa_enum_decode(buf, len, tp, val)
+ *
+ * @param buf buffer for result (may be used or not).
+ * @param len size of buffer (at least 32 bytes recommended).
+ * @param tp pointer to table of names and values, struct sa_nameval.
+ * @param val value to be decoded into a name.
+ * @returns pointer to name string.  Unknown values are put into buffer in hex.
+ */
+const char *
+sa_enum_decode(char *buf, size_t len,
+		const struct sa_nameval *tp, u_int32_t val)
+{
+	for (; tp->nv_name != NULL; tp++) {
+		if (tp->nv_val == val)
+			return tp->nv_name;
+	}
+	snprintf(buf, len, "Unknown (code 0x%X)", val);
+	return buf;
+}
+
+/*
+ * Read through a directory and call a function for each entry.
+ */
+int
+sa_dir_read(char *dir_name, int (*func)(struct dirent *dp, void *), void *arg)
+{
+	DIR *dir;
+	struct dirent *dp;
+	int error = 0;
+
+	dir = opendir(dir_name);
+	if (dir == NULL)
+		error = errno;
+	else {
+		while ((dp = readdir(dir)) != NULL && error == 0) {
+			if (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' ||
+			   (dp->d_name[1] == '.' && dp->d_name[2] == '\0')))
+				continue;
+			error = (*func)(dp, arg);
+		}
+		closedir(dir);
+	}
+	return error;
+}
+
+/*
+ * Size of on-stack line buffers.
+ * These shouldn't be to large for a kernel stack frame.
+ */
+#define SA_LOG_BUF_LEN  200	/* on-stack line buffer size */
+
+static const u_int32_t sa_table_growth = 16;        /* entries to grow by */
+
+/** sa_table_grow(tp, index) - add space to a table for index.
+ *
+ * @param tp pointer to sa_table structure.
+ * @param index - new index past the end of the current table.
+ * @returns new index, or -1 if table couldn't be grown.
+ *
+ * Note: if the table has never been used, and is still all zero, this works.
+ *
+ * Note: perhaps not safe for multithreading.  Caller can lock the table
+ * externally, but reallocation can take a while, during which time the
+ * caller may not wish to hold the lock.
+ */
+int
+sa_table_grow(struct sa_table *tp, u_int32_t index)
+{
+	u_int32_t new_size;
+	void **ap;
+
+	if (index >= tp->st_size) {
+		new_size = index + sa_table_growth;
+		ap = realloc(tp->st_table, new_size * sizeof(*ap));
+		if (ap == NULL)
+			return -1;
+		memset(ap + tp->st_size, 0,
+			(new_size - tp->st_size) * sizeof(*ap));
+		tp->st_table = ap;
+		tp->st_size = new_size;
+	}
+	tp->st_limit = index + 1;
+	return index;
+}
+
+/** sa_table_destroy(tp) - free memory used by table.
+ *
+ * @param tp pointer to sa_table structure.
+ */
+void
+sa_table_destroy(struct sa_table *tp)
+{
+	if (tp->st_table) {
+		free(tp->st_table);
+		tp->st_table = NULL;
+	}
+	tp->st_limit = 0;
+	tp->st_size = 0;
+}
+
+/** sa_table_destroy_all(tp) - free memory used by table, including entries.
+ *
+ * @param tp pointer to sa_table structure.
+ */
+void
+sa_table_destroy_all(struct sa_table *tp)
+{
+	int  i;
+
+	if (tp->st_table) {
+		for (i = 0; i < tp->st_limit; i++) {
+			if (tp->st_table[i]) {
+				free(tp->st_table[i]);
+				tp->st_table[i] = NULL;
+			}
+		}
+	}
+	sa_table_destroy(tp);
+}
+
+/** sa_table_iterate(tp, handler, arg)
+ *
+ * @param tp pointer to sa_table structure.
+ * @param handler function to be called for each non-NULL entry.
+ * @param arg argument for function.
+ */
+void
+sa_table_iterate(struct sa_table *tp,
+		 void (*handler)(void *ep, void *arg),
+		 void *arg)
+{
+	int i;
+	void *ep;
+
+	for (i = 0; i < tp->st_limit; i++) {
+		ep = tp->st_table[i];
+		if (ep != NULL)
+			(*handler)(ep, arg);
+	}
+}
+
+/** sa_table_search(tp, match, arg)
+ *
+ * @param tp pointer to sa_table structure.
+ * @param match function to compare entries with arg and
+ *	 return non-NULL if match.
+ * @param arg argument for match function.
+ *
+ * Note that the value found could actually be something not in the table
+ * if the match function is doing something clever, like returning a
+ * sub-structure of the table entry.
+ */
+void *
+sa_table_search(struct sa_table *tp, void *(*match)(void *ep, void *arg),
+	void *arg)
+{
+	int i;
+	void *found = NULL;
+	void *ep;
+
+	for (i = 0; i < tp->st_limit; i++) {
+		ep = tp->st_table[i];
+		found = (*match)(ep, arg);
+		if (ep != NULL && found != NULL)
+			break;
+	}
+	return found;
+}
diff --git a/src/utils.h b/src/utils.h
new file mode 100644
index 0000000..9228c26
--- /dev/null
+++ b/src/utils.h
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2008, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU Lesser General Public License,
+ * version 2.1, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef _UTILS_H_
+#define _UTILS_H_
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <linux/types.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <string.h>
+#include <time.h>
+#include <fcntl.h>
+#include <malloc.h>
+#include <pthread.h>
+#include <limits.h>
+#include <scsi/sg.h>
+#include "hbaapi.h"
+#include "vendorhbaapi.h"
+#include "fc_types.h"
+
+/*
+ * Structure for tables encoding and decoding name-value pairs such as enums.
+ */
+struct sa_nameval {
+	char        *nv_name;
+	u_int32_t   nv_val;
+};
+
+/*
+ * Structure for integer-indexed tables that can grow.
+ */
+struct sa_table {
+	u_int32_t   st_size;        /* number of entries in table */
+	u_int32_t   st_limit;       /* end of valid entries in table (public) */
+	void        **st_table;     /* re-allocatable array of pointers */
+};
+
+/*
+ * Function prototypes
+ */
+extern int sa_sys_read_line(const char *, const char *, char *, size_t);
+extern int sa_sys_write_line(const char *, const char *, const char *);
+extern int sa_sys_read_u32(const char *, const char *, u_int32_t *);
+extern int sa_sys_read_u64(const char *, const char *, u_int64_t *);
+extern int sa_dir_read(char *, int (*)(struct dirent *, void *), void *);
+extern char *sa_strncpy_safe(char *dest, size_t len,
+			     const char *src, size_t src_len);
+extern const char *sa_enum_decode(char *, size_t,
+				  const struct sa_nameval *, u_int32_t);
+extern int sa_enum_encode(const struct sa_nameval *tp,
+			const char *, u_int32_t *);
+extern const char *sa_flags_decode(char *, size_t,
+				   const struct sa_nameval *, u_int32_t);
+extern int sa_table_grow(struct sa_table *, u_int32_t index);
+extern void sa_table_destroy_all(struct sa_table *);
+extern void sa_table_destroy(struct sa_table *);
+extern void sa_table_iterate(struct sa_table *tp,
+			void (*handler)(void *ep, void *arg), void *arg);
+extern void *sa_table_search(struct sa_table *tp,
+			void *(*match)(void *ep, void *arg), void *arg);
+
+/** sa_table_init(tp) - initialize a table.
+ * @param tp table pointer.
+ *
+ * This just clears a table structure that was allocated by the caller.
+ */
+static inline void sa_table_init(struct sa_table *tp)
+{
+	memset(tp, 0, sizeof(*tp));
+}
+
+/** sa_table_lookup(tp, index) - lookup an entry in the table.
+ * @param tp table pointer.
+ * @param index the index in the table to access
+ * @returns the entry, or NULL if the index wasn't valid.
+ */
+static inline void *sa_table_lookup(const struct sa_table *tp, u_int32_t index)
+{
+	void *ep = NULL;
+
+	if (index < tp->st_limit)
+		ep = tp->st_table[index];
+	return ep;
+}
+
+/** sa_table_lookup_n(tp, n) - find Nth non-empty entry in a table.
+ * @param tp table pointer.
+ * @param n is the entry number, the first non-empty entry is 0.
+ * @returns the entry, or NULL if the end of the table reached first.
+ */
+static inline void *sa_table_lookup_n(const struct sa_table *tp, u_int32_t n)
+{
+	void *ep = NULL;
+	u_int32_t   i;
+
+	for (i = 0; i < tp->st_limit; i++) {
+		ep = tp->st_table[i];
+		if (ep != NULL && n-- == 0)
+			return ep;
+	}
+	return NULL;
+}
+
+/** sa_table_insert(tp, index, ep) - Replace or insert an entry in the table.
+ * @param tp table pointer.
+ * @param index the index for the new entry.
+ * @param ep entry pointer.
+ * @returns index on success, or -1 if the insert failed.
+ *
+ * Note: if the table has never been used, and is still all zero, this works.
+ *
+ * Note: perhaps not safe for multithreading.  Caller can lock the table
+ * externally, but reallocation can take a while, during which time the
+ * caller may not wish to hold the lock.
+ */
+static inline int sa_table_insert(struct sa_table *tp,
+				  u_int32_t index, void *ep)
+{
+	if (index >= tp->st_limit && sa_table_grow(tp, index) < 0)
+		return -1;
+	tp->st_table[index] = ep;
+	return index;
+}
+
+/** sa_table_append(tp, ep) - add entry to table and return index.
+ *
+ * @param tp pointer to sa_table structure.
+ * @param ep pointer to new entry, to be added at the end of the table.
+ * @returns new index, or -1 if table couldn't be grown.
+ *
+ * See notes on sa_table_insert().
+ */
+static inline int
+sa_table_append(struct sa_table *tp, void *ep)
+{
+	return sa_table_insert(tp, tp->st_limit, ep);
+}
+
+/** sa_table_sort(tp, compare) - sort table in place
+ *
+ * @param tp pointer to sa_table structure.
+ * @param compare function to compare two entries.  It is called with pointers
+ * to the pointers to the entries to be compared.  See qsort(3).
+ */
+static inline void
+sa_table_sort(struct sa_table *tp, int (*compare)(const void **, const void **))
+{
+	qsort(tp->st_table, tp->st_limit, sizeof(void *),
+		(int (*)(const void *, const void *)) compare);
+}
+
+#endif /* _UTILS_H_ */




More information about the devel mailing list