diff -Naurp open-iscsi-2.0-868-test1.work3/include/fw_context.h open-iscsi-2.0-868-test1.work2/include/fw_context.h
--- open-iscsi-2.0-868-test1.work3/include/fw_context.h	2008-11-30 20:44:12.000000000 -0600
+++ open-iscsi-2.0-868-test1.work2/include/fw_context.h	2008-11-30 20:43:24.000000000 -0600
@@ -21,7 +21,11 @@
 #ifndef FWPARAM_CONTEXT_H_
 #define FWPARAM_CONTEXT_H_
 
+#include "list.h"
+
 struct boot_context {
+	struct list_head list;
+
 #define IQNSZ (223+1)
 #define CHAPSZ (255+1)
 	/* target settings */
@@ -52,5 +56,7 @@ struct boot_context {
 
 extern int fw_get_entry(struct boot_context *context, const char *filepath);
 extern void fw_print_entry(struct boot_context *context);
+extern int fw_get_targets(struct list_head *list);
+extern void fw_free_targets(struct list_head *list);
 
 #endif /* FWPARAM_CONTEXT_H_ */
diff -Naurp open-iscsi-2.0-868-test1.work3/include/list.h open-iscsi-2.0-868-test1.work2/include/list.h
--- open-iscsi-2.0-868-test1.work3/include/list.h	1969-12-31 18:00:00.000000000 -0600
+++ open-iscsi-2.0-868-test1.work2/include/list.h	2008-11-30 20:43:24.000000000 -0600
@@ -0,0 +1,93 @@
+#ifndef __LIST_H__
+#define __LIST_H__
+
+#include <stddef.h>
+/* taken from linux kernel */
+
+#undef offsetof
+#ifdef __compiler_offsetof
+#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
+#else
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+
+#define container_of(ptr, type, member) ({			\
+        const typeof( ((type *)0)->member ) *__mptr = (ptr);	\
+        (type *)( (char *)__mptr - offsetof(type,member) );})
+
+struct list_head {
+	struct list_head *next, *prev;
+};
+
+#define LIST_HEAD_INIT(name) { &(name), &(name) }
+
+#define LIST_HEAD(name) \
+	struct list_head name = LIST_HEAD_INIT(name)
+
+static inline void INIT_LIST_HEAD(struct list_head *list)
+{
+	list->next = list;
+	list->prev = list;
+}
+
+static inline int list_empty(const struct list_head *head)
+{
+	return head->next == head;
+}
+
+#define list_entry(ptr, type, member) \
+	container_of(ptr, type, member)
+
+#define list_for_each(pos, head) \
+	for (pos = (head)->next; pos != (head); pos = pos->next)
+
+#define list_for_each_entry(pos, head, member)				\
+	for (pos = list_entry((head)->next, typeof(*pos), member);	\
+	     &pos->member != (head);				 	\
+	     pos = list_entry(pos->member.next, typeof(*pos), member))
+
+#define list_for_each_entry_safe(pos, n, head, member)			\
+	for (pos = list_entry((head)->next, typeof(*pos), member),	\
+		n = list_entry(pos->member.next, typeof(*pos), member);	\
+	     &pos->member != (head); 					\
+	     pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+static inline void __list_add(struct list_head *new,
+			      struct list_head *prev,
+			      struct list_head *next)
+{
+	next->prev = new;
+	new->next = next;
+	new->prev = prev;
+	prev->next = new;
+}
+
+static inline void list_add(struct list_head *new, struct list_head *head)
+{
+	__list_add(new, head, head->next);
+}
+
+static inline void list_add_tail(struct list_head *new, struct list_head *head)
+{
+	__list_add(new, head->prev, head);
+}
+
+static inline void __list_del(struct list_head * prev, struct list_head * next)
+{
+	next->prev = prev;
+	prev->next = next;
+}
+
+static inline void list_del(struct list_head *entry)
+{
+	__list_del(entry->prev, entry->next);
+	entry->next = entry->prev = NULL;
+}
+
+static inline void list_del_init(struct list_head *entry)
+{
+	__list_del(entry->prev, entry->next);
+	INIT_LIST_HEAD(entry);
+}
+
+#endif
diff -Naurp open-iscsi-2.0-868-test1.work3/usr/idbm.c open-iscsi-2.0-868-test1.work2/usr/idbm.c
--- open-iscsi-2.0-868-test1.work3/usr/idbm.c	2008-11-30 20:44:12.000000000 -0600
+++ open-iscsi-2.0-868-test1.work2/usr/idbm.c	2008-11-30 20:46:57.000000000 -0600
@@ -35,6 +35,7 @@
 #include "iscsi_settings.h"
 #include "transport.h"
 #include "iscsi_sysfs.h"
+#include "version.h"
 
 #define IDBM_HIDE	0    /* Hide parameter when print. */
 #define IDBM_SHOW	1    /* Show parameter when print. */
@@ -434,6 +435,7 @@ idbm_print(int type, void *rec, int show
 		break;
 	}
 
+	fprintf(f, "# BEGIN RECORD %s\n", ISCSI_VERSION_STR);
 	for (i = 0; i < MAX_KEYS; i++) {
 		if (!info[i].visible)
 			continue;
@@ -450,6 +452,7 @@ idbm_print(int type, void *rec, int show
 		else if (f == stdout)
 			fprintf(f, "%s = <empty>\n", info[i].name);
 	}
+	fprintf(f, "# END RECORD\n");
 
 	free(info);
 }
diff -Naurp open-iscsi-2.0-868-test1.work3/usr/iscsiadm.c open-iscsi-2.0-868-test1.work2/usr/iscsiadm.c
--- open-iscsi-2.0-868-test1.work3/usr/iscsiadm.c	2008-11-30 20:44:12.000000000 -0600
+++ open-iscsi-2.0-868-test1.work2/usr/iscsiadm.c	2008-11-30 20:43:24.000000000 -0600
@@ -1878,32 +1878,48 @@ fw_create_rec_by_entry(idbm_t *db, struc
 static int exec_fw_op(idbm_t *db, discovery_rec_t *drec, int do_login,
 		     int info_level)
 {
-	struct boot_context context;
+	struct boot_context *context;
 	struct node_rec *rec;
+	struct list_head targets;
 	int ret = 0;
 
-	memset(&context, 0, sizeof(struct boot_context));
-	ret = fw_get_entry(&context, NULL);
+	INIT_LIST_HEAD(&targets);
+
+	ret = fw_get_targets(&targets);
 	if (ret) {
-		log_error("Could not read fw values.");
+		log_error("Could not get list of targets from firmware.\n");
 		return ret;
 	}
 
-	rec = fw_create_rec_by_entry(db, &context);
-	if (!rec)
-		return ENODEV;
-
-	/* if discovery, print nodes that were found. */
-	if (drec)
-		print_fw_nodes(rec, info_level);
-
-	if (do_login)
-		ret = login_portal(db, NULL, rec);
-	free(rec);
-
-	/* print the fw node info if called in fw mode with no params */
-	if (!do_login && !drec)
-		fw_print_entry(&context);
+	list_for_each_entry(context, &targets, list) {
+		rec = fw_create_rec_by_entry(db, context);
+		if (!rec) {
+			log_error("Could not convert firmware info to "
+				  "node record.\n");
+			break;
+		}
+
+		if (drec) {
+			ret = idbm_add_node(db, rec, NULL);
+			if (ret) {
+				log_error("Could not add node record. "
+					  "(err %d)\n", ret);
+				break;
+			}
+
+			print_fw_nodes(rec, info_level);
+		}
+
+		if (do_login)
+			ret = login_portal(db, NULL, rec);
+		free(rec);
+
+		/* print the fw node info if called in fw mode with no params */
+		if (!do_login && !drec)
+			fw_print_entry(context);
+	}
+
+	fw_free_targets(&targets);
 	return ret;
 }
 
diff -Naurp open-iscsi-2.0-868-test1.work3/usr/iscsistart.c open-iscsi-2.0-868-test1.work2/usr/iscsistart.c
--- open-iscsi-2.0-868-test1.work3/usr/iscsistart.c	2008-11-30 20:44:12.000000000 -0600
+++ open-iscsi-2.0-868-test1.work2/usr/iscsistart.c	2008-11-30 20:43:24.000000000 -0600
@@ -50,6 +50,7 @@ struct iscsi_daemon_config daemon_config
 struct iscsi_daemon_config *dconfig = &daemon_config;
 
 static node_rec_t config_rec;
+static LIST_HEAD(targets);
 
 static char program_name[] = "iscsistart";
 static int mgmt_ipc_fd;
@@ -120,7 +121,8 @@ static int stop_event_loop(void)
 	return rc;
 }
 
-static int setup_session(void)
+
+static int login_session(void)
 {
 	iscsiadm_req_t req;
 	iscsiadm_rsp_t rsp;
@@ -145,7 +147,45 @@ static int setup_session(void)
 	rc = do_iscsid(&req, &rsp);
 	if (rc)
 		iscsid_handle_error(rc);
+	return rc;
+}
+
+static int setup_session(void)
+{
+	struct boot_context *context;
+	struct iscsi_auth_config *auth;
+	int rc = 0, rc2 = 0;
+
+	if (list_empty(&targets))
+		return login_session();
 
+	list_for_each_entry(context, &targets, list) {
+		idbm_node_setup_defaults(&config_rec);
+
+		auth = &config_rec.session.auth;
+		strncpy(config_rec.name, context->targetname,
+			sizeof(context->targetname));
+		strncpy(config_rec.conn[0].address, context->target_ipaddr,
+			sizeof(context->target_ipaddr));
+		config_rec.conn[0].port = context->target_port;
+		/* this seems broken ??? */
+		config_rec.tpgt = 1;
+		strncpy(auth->username, context->chap_name,
+			sizeof(context->chap_name));
+		strncpy((char *)auth->password, context->chap_password,
+			sizeof(context->chap_password));
+		auth->password_length = strlen((char *)auth->password);
+		strncpy(auth->username_in, context->chap_name_in,
+			sizeof(context->chap_name_in));
+		strncpy((char *)auth->password_in, context->chap_password_in,
+			sizeof(context->chap_password_in));
+		auth->password_in_length = strlen((char *)auth->password_in);
+
+		rc2 = login_session();
+		if (rc2)
+			rc = rc2;
+	}
+	fw_free_targets(&targets);
 	return rc;
 }
 
@@ -194,9 +234,9 @@ int main(int argc, char *argv[])
 	struct iscsi_auth_config *auth;
 	char *initiatorname = NULL;
 	int ch, longindex, ret;
+	struct boot_context *context, boot_context;
 	struct sigaction sa_old;
 	struct sigaction sa_new;
-	struct boot_context context;
 	pid_t pid;
 
 	idbm_node_setup_defaults(&config_rec);
@@ -260,42 +300,32 @@ int main(int argc, char *argv[])
 			log_level = atoi(optarg);
 			break;
 		case 'b':
-			ret = fw_get_entry(&context, NULL);
+			memset(&boot_context, 0, sizeof(boot_context));
+			ret = fw_get_entry(&boot_context, NULL);
 			if (ret) {
-				printf("Could not setup fw entries.");
-				exit(-1);
+				printf("Could not get boot entry.\n");
+				exit(1);
 			}
 
-			initiatorname = context.initiatorname;
-			strncpy(config_rec.name, context.targetname,
-				sizeof(context.targetname));
-			strncpy(config_rec.conn[0].address,
-				context.target_ipaddr,
-				sizeof(context.target_ipaddr));
-			config_rec.conn[0].port = context.target_port;
-			/* this seems broken ??? */
-			config_rec.tpgt = 1;
-			strncpy(auth->username, context.chap_name,
-				sizeof(context.chap_name));
-			strncpy((char *)auth->password, context.chap_password,
-				sizeof(context.chap_password));
-			auth->password_length = strlen((char *)auth->password);
-			strncpy(auth->username_in, context.chap_name_in,
-				sizeof(context.chap_name_in));
-			strncpy((char *)auth->password_in,
-				context.chap_password_in,
-				sizeof(context.chap_password_in));
-			auth->password_in_length =
-					strlen((char *)auth->password_in);
+			initiatorname = boot_context.initiatorname;
+			ret = fw_get_targets(&targets);
+			if (ret || list_empty(&targets)) {
+				printf("Could not setup fw entries.\n");
+				exit(1);
+			}
 			break;
 		case 'f':
-			ret = fw_get_entry(&context, NULL);
-			if (ret) {
-				printf("Could not read fw values.\n");
-				exit(-1);
+			ret = fw_get_targets(&targets);
+			if (ret || list_empty(&targets)) {
+				printf("Could not get list of targets from "
+				       "firmware.\n");
+				exit(1);
 			}
 
-			fw_print_entry(&context);
+			list_for_each_entry(context, &targets, list)
+				fw_print_entry(context);
+
+			fw_free_targets(&targets);
 			exit(0);
 		case 'v':
 			printf("%s version %s\n", program_name,
@@ -317,7 +347,7 @@ int main(int argc, char *argv[])
 	if (check_class_version())
 		exit(1);
 
-	if (check_params(initiatorname))
+	if (list_empty(&targets) && check_params(initiatorname))
 		exit(1);
 
 	pid = fork();
diff -Naurp open-iscsi-2.0-868-test1.work3/usr/list.h open-iscsi-2.0-868-test1.work2/usr/list.h
--- open-iscsi-2.0-868-test1.work3/usr/list.h	2008-11-30 20:44:12.000000000 -0600
+++ open-iscsi-2.0-868-test1.work2/usr/list.h	1969-12-31 18:00:00.000000000 -0600
@@ -1,92 +0,0 @@
-#ifndef __LIST_H__
-#define __LIST_H__
-
-/* taken from linux kernel */
-
-#undef offsetof
-#ifdef __compiler_offsetof
-#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
-#else
-#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
-#endif
-
-#define container_of(ptr, type, member) ({			\
-        const typeof( ((type *)0)->member ) *__mptr = (ptr);	\
-        (type *)( (char *)__mptr - offsetof(type,member) );})
-
-struct list_head {
-	struct list_head *next, *prev;
-};
-
-#define LIST_HEAD_INIT(name) { &(name), &(name) }
-
-#define LIST_HEAD(name) \
-	struct list_head name = LIST_HEAD_INIT(name)
-
-static inline void INIT_LIST_HEAD(struct list_head *list)
-{
-	list->next = list;
-	list->prev = list;
-}
-
-static inline int list_empty(const struct list_head *head)
-{
-	return head->next == head;
-}
-
-#define list_entry(ptr, type, member) \
-	container_of(ptr, type, member)
-
-#define list_for_each(pos, head) \
-	for (pos = (head)->next; pos != (head); pos = pos->next)
-
-#define list_for_each_entry(pos, head, member)				\
-	for (pos = list_entry((head)->next, typeof(*pos), member);	\
-	     &pos->member != (head);				 	\
-	     pos = list_entry(pos->member.next, typeof(*pos), member))
-
-#define list_for_each_entry_safe(pos, n, head, member)			\
-	for (pos = list_entry((head)->next, typeof(*pos), member),	\
-		n = list_entry(pos->member.next, typeof(*pos), member);	\
-	     &pos->member != (head); 					\
-	     pos = n, n = list_entry(n->member.next, typeof(*n), member))
-
-static inline void __list_add(struct list_head *new,
-			      struct list_head *prev,
-			      struct list_head *next)
-{
-	next->prev = new;
-	new->next = next;
-	new->prev = prev;
-	prev->next = new;
-}
-
-static inline void list_add(struct list_head *new, struct list_head *head)
-{
-	__list_add(new, head, head->next);
-}
-
-static inline void list_add_tail(struct list_head *new, struct list_head *head)
-{
-	__list_add(new, head->prev, head);
-}
-
-static inline void __list_del(struct list_head * prev, struct list_head * next)
-{
-	next->prev = prev;
-	prev->next = next;
-}
-
-static inline void list_del(struct list_head *entry)
-{
-	__list_del(entry->prev, entry->next);
-	entry->next = entry->prev = NULL;
-}
-
-static inline void list_del_init(struct list_head *entry)
-{
-	__list_del(entry->prev, entry->next);
-	INIT_LIST_HEAD(entry);
-}
-
-#endif
diff -Naurp open-iscsi-2.0-868-test1.work3/utils/fwparam_ibft/fw_entry.c open-iscsi-2.0-868-test1.work2/utils/fwparam_ibft/fw_entry.c
--- open-iscsi-2.0-868-test1.work3/utils/fwparam_ibft/fw_entry.c	2008-11-30 20:44:12.000000000 -0600
+++ open-iscsi-2.0-868-test1.work2/utils/fwparam_ibft/fw_entry.c	2008-11-30 20:43:24.000000000 -0600
@@ -20,20 +20,66 @@
 #include <stddef.h>
 #include <stdio.h>
 #include <string.h>
+#include <stdlib.h>
+
 #include "fw_context.h"
-#include "fwparam_ibft.h"
+#include "fwparam.h"
 
+/**
+ * fw_get_entry - return boot context of portal used for boot
+ * @context: firmware info of portal
+ * @filepath: CURRENTLY NOT USED
+ *
+ * Returns non-zero if no portal was used for boot.
+ *
+ * This function is not thread safe.
+ */
 int fw_get_entry(struct boot_context *context, const char *filepath)
 {
 	int ret;
 
-	ret = fwparam_ppc(context, filepath);
+	ret = fwparam_ppc_boot_info(context);
+	if (ret)
+		ret = fwparam_ibft_sysfs_boot_info(context);
+
+	return ret;
+}
+
+/**
+ * fw_get_targets - get a boot_context struct for each target
+ * @list: list to add entires on.
+ *
+ * Returns zero if entries were found that can be traversed with the
+ * list.h helpers, or non-zero if no entries are found.
+ *
+ * fw_free_targets should be called to free the list.
+ *
+ * This function is not thread safe.
+ */
+int fw_get_targets(struct list_head *list)
+{
+	int ret;
+
+	ret = fwparam_ppc_get_targets(list);
 	if (ret)
-		ret = fwparam_ibft_sysfs(context, filepath);
+		ret = fwparam_ibft_sysfs_get_targets(list);
 
 	return ret;
 }
 
+void fw_free_targets(struct list_head *list)
+{
+	struct boot_context *curr, *tmp;
+
+	if (!list || list_empty(list))
+		return;
+
+	list_for_each_entry_safe(curr, tmp, list, list) {
+		list_del(&curr->list);
+		free(curr);
+	}
+}
+
 static void dump_initiator(struct boot_context *context)
 {
 	if (strlen(context->initiatorname))
@@ -99,9 +145,19 @@ static void dump_network(struct boot_con
 		printf("iface.net_ifacename = %s\n", context->iface);
 }
 
+/**
+ * fw_print_entry - print boot context info of portal used for boot
+ * @context: firmware info of portal
+ *
+ * Does not print anything if no portal was used for boot.
+ *
+ * TODO: Merge this in with idbm.c helpers.
+ */
 void fw_print_entry(struct boot_context *context)
 {
+	printf("# BEGIN RECORD\n");
 	dump_initiator(context);
 	dump_network(context);
 	dump_target(context);
+	printf("# END RECORD\n");
 }
diff -Naurp open-iscsi-2.0-868-test1.work3/utils/fwparam_ibft/fwparam.h open-iscsi-2.0-868-test1.work2/utils/fwparam_ibft/fwparam.h
--- open-iscsi-2.0-868-test1.work3/utils/fwparam_ibft/fwparam.h	1969-12-31 18:00:00.000000000 -0600
+++ open-iscsi-2.0-868-test1.work2/utils/fwparam_ibft/fwparam.h	2008-11-30 20:43:24.000000000 -0600
@@ -0,0 +1,32 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+ * USA.
+ */
+#ifndef FWPARAM_H_
+#define FWPARAM_H_
+
+#include <stdint.h>
+#include "fw_context.h"
+
+#define FILENAMESZ (256)
+
+struct boot_context;
+
+int fwparam_ibft_sysfs_boot_info(struct boot_context *context);
+int fwparam_ibft_sysfs_get_targets(struct list_head *list);
+int fwparam_ppc_boot_info(struct boot_context *context);
+int fwparam_ppc_get_targets(struct list_head *list);
+
+#endif /* FWPARAM_IBFT_H_ */
diff -Naurp open-iscsi-2.0-868-test1.work3/utils/fwparam_ibft/fwparam_ibft.h open-iscsi-2.0-868-test1.work2/utils/fwparam_ibft/fwparam_ibft.h
--- open-iscsi-2.0-868-test1.work3/utils/fwparam_ibft/fwparam_ibft.h	2008-11-30 20:44:12.000000000 -0600
+++ open-iscsi-2.0-868-test1.work2/utils/fwparam_ibft/fwparam_ibft.h	2008-11-30 20:43:24.000000000 -0600
@@ -145,15 +145,5 @@ extern char filename[FILENAMESZ];
 extern int debug;
 extern int dev_count;
 
-/*
- * Prefix strings, for the "prefixN:NAME=value".
- */
-#define NETWORK		"network"
-#define INITIATOR	"iscsi-initiator"
-#define TARGET		"target"
-
 extern int fwparam_ibft(struct boot_context *context, const char *filepath);
-extern int fwparam_ibft_sysfs(struct boot_context *context,
-			const char *filepath);
-extern int fwparam_ppc(struct boot_context *context, const char *filepath);
 #endif /* FWPARAM_IBFT_H_ */
diff -Naurp open-iscsi-2.0-868-test1.work3/utils/fwparam_ibft/fwparam_ibft_sysfs.c open-iscsi-2.0-868-test1.work2/utils/fwparam_ibft/fwparam_ibft_sysfs.c
--- open-iscsi-2.0-868-test1.work3/utils/fwparam_ibft/fwparam_ibft_sysfs.c	2008-11-30 20:44:12.000000000 -0600
+++ open-iscsi-2.0-868-test1.work2/utils/fwparam_ibft/fwparam_ibft_sysfs.c	2008-11-30 20:43:50.000000000 -0600
@@ -25,14 +25,13 @@
 #include <fcntl.h>
 #include <errno.h>
 #include <dirent.h>
-#include <fw_context.h>
 #include <sys/types.h>
 
-#include "fwparam_ibft.h"
+#include "fw_context.h"
+#include "fwparam.h"
 
 #define IBFT_MAX 255
 #define IBFT_SYSFS_ROOT "/sys/firmware/ibft/"
-#define IBFT_SYSFS_DE
 
 static char *target_list[IBFT_MAX];
 static char *nic_list[IBFT_MAX];
@@ -107,9 +106,6 @@ static int read_data(const char *dir, co
 
 	if (file_exist(file))  {
 		rc = read_file(file, &data);
-		if (debug)
-			fprintf(stderr, "(%s:%d) Read from %s:[%s]\n",
-				__FILE__, __LINE__, file, data);
 		if (!rc)
 			memcpy(dst, data, size);
 		free(data);
@@ -224,7 +220,7 @@ static int fill_initiator_context(const 
 
 	rc |= read_data(dir, "/initiator-name", context->initiatorname,
 		sizeof(context->initiatorname));
-	rc |= read_data(dir, "/isns-server", context->isid,
+	rc |= read_data(dir, "/isid", context->isid,
 		sizeof(context->isid));
 
 	return rc;
@@ -290,17 +286,14 @@ static void deallocate_lists(void)
 
 }
 
-int fwparam_ibft_sysfs(struct boot_context *context, const char *filepath)
+int fwparam_ibft_sysfs_boot_info(struct boot_context *context)
 {
 	char initiator_dir[FILENAMESZ];
-	char *root_sysfs = NULL;
+	char *root_sysfs = IBFT_SYSFS_ROOT;
 	int rc = 1;
 	int nic_idx = -1, tgt_idx = -1;
 
-	if (filepath)
-		root_sysfs = (char *)filepath;
-	else
-		root_sysfs = IBFT_SYSFS_ROOT;
+	root_sysfs = IBFT_SYSFS_ROOT;
 
 	memset(&initiator_dir, 0 , FILENAMESZ);
 	strncat(initiator_dir, root_sysfs, FILENAMESZ);
@@ -330,3 +323,66 @@ free:
 	deallocate_lists();
 	return rc;
 }
+
+int fwparam_ibft_sysfs_get_targets(struct list_head *list)
+{
+	struct boot_context *context;
+	int rc = 0, i, nic_idx, nic;
+	char initiator_dir[FILENAMESZ];
+
+	memset(&initiator_dir, 0 , FILENAMESZ);
+	strncat(initiator_dir, IBFT_SYSFS_ROOT, FILENAMESZ);
+	strncat(initiator_dir, "initiator", FILENAMESZ);
+
+	if (!file_exist(initiator_dir))
+		return ENODEV;
+
+	/* Find the target's and the ethernet's */
+	nftw(IBFT_SYSFS_ROOT, find_sysfs_dirs, 20, 1);
+	for (i = 0; i < tgt_cnt; i++) {	
+		context = calloc(1, sizeof(*context));
+		if (!context) {
+			rc = ENOMEM;
+			break;
+		}
+
+		rc = fill_tgt_context(target_list[i], context);
+		if (rc)
+			break;
+
+		rc = read_int_data(target_list[i], "/nic-assoc", &nic_idx);
+		if (rc)
+			break;
+		for (nic = 0; nic < nic_cnt; nic++) {
+			int id;
+
+			rc = read_int_data(nic_list[nic], "/index", &id);
+			if (!rc && (id == nic_idx))
+				break;
+		}
+
+		if (nic == nic_cnt) {
+			printf("Invalid nic-assoc of %d. Max id %d.\n",
+			       nic_idx, nic_cnt);
+			break;
+		}
+
+		rc = fill_nic_context(nic_list[nic], context);
+		if (rc)
+			break;
+
+		rc = fill_initiator_context(initiator_dir, context);
+		if (rc)
+			break;
+
+		list_add_tail(&context->list, list);
+	}
+
+	if (rc) {
+		free(context);
+		fw_free_targets(list);
+	}
+
+	deallocate_lists();
+	return rc;
+}
diff -Naurp open-iscsi-2.0-868-test1.work3/utils/fwparam_ibft/fwparam_ppc.c open-iscsi-2.0-868-test1.work2/utils/fwparam_ibft/fwparam_ppc.c
--- open-iscsi-2.0-868-test1.work3/utils/fwparam_ibft/fwparam_ppc.c	2008-11-30 20:44:12.000000000 -0600
+++ open-iscsi-2.0-868-test1.work2/utils/fwparam_ibft/fwparam_ppc.c	2008-11-30 20:43:24.000000000 -0600
@@ -25,7 +25,7 @@
 #include <fcntl.h>
 #include <errno.h>
 
-#include "fwparam_ibft.h"
+#include "fwparam.h"
 #include "fw_context.h"
 #include "iscsi_obp.h"
 #include "prom_parse.h"
@@ -44,6 +44,8 @@ static int bytes_read;
 static struct ofw_dev *ofwdevs[OFWDEV_MAX];
 static char *niclist[OFWDEV_MAX];
 static int nic_count;
+static int debug;
+static int dev_count;
 
 static void cp_param(char *dest, const char *name, struct ofw_dev *dev,
 		     enum obp_param item, int len)
@@ -114,7 +116,7 @@ static int locate_mac(const char *devtre
 	mac_file = malloc(mac_path_len);
 	if (!mac_file) {
 		error = ENOMEM;
-		fprintf(stderr, "%s: malloc %s, %s\n", __func__, filename,
+		fprintf(stderr, "%s: malloc , %s\n", __func__,
 			strerror(errno));
 		goto lpm_bail;
 	}
@@ -422,8 +424,9 @@ static void fill_context(struct boot_con
 
 }
 
-int fwparam_ppc(struct boot_context *context, const char *filepath)
+int fwparam_ppc_boot_info(struct boot_context *context)
 {
+	char filename[FILENAMESZ];
 	int error;
 	int fplen = 0;
 	char *devtree;
@@ -435,12 +438,7 @@ int fwparam_ppc(struct boot_context *con
 	 * systems that can support iscsi are the ones that provide
 	 * the appropriate FCODE with a load method.
 	 */
-	if (filepath) {
-		strncat(filename, filepath, FILENAMESZ);
-		fplen = strlen(filename);
-	} else
-		strncat(filename, DT_TOP, FILENAMESZ);
-
+	strncat(filename, DT_TOP, FILENAMESZ);
 	strncat(filename + fplen, BOOTPATH, FILENAMESZ - fplen);
 
 	if (debug)
@@ -487,7 +485,86 @@ int fwparam_ppc(struct boot_context *con
 
 		if (!error)
 			fill_context(context, ofwdevs[0]);
+	
+	}
+
+	return error;
+}
+
+/*
+ * Due to lack of time this is just fwparam_ppc_boot_info which
+ * adds the target used for boot to the list. It does not add
+ * all possible targets (IBM please add).
+ */
+int fwparam_ppc_get_targets(struct list_head *list)
+{
+	char filename[FILENAMESZ];
+	struct boot_context *context;
+	int error;
+	int fplen = 0;
+	char *devtree;
+
+	/*
+	 * For powerpc, our operations are fundamentally to locate
+	 * either the one boot target (the singleton disk), or to find
+	 * the nics that support iscsi boot.  The only nics in IBM
+	 * systems that can support iscsi are the ones that provide
+	 * the appropriate FCODE with a load method.
+	 */
+	strncat(filename, DT_TOP, FILENAMESZ);
+	strncat(filename + fplen, BOOTPATH, FILENAMESZ - fplen);
+
+	if (debug)
+		fprintf(stderr, "%s: file:%s; debug:%d\n", __func__, filename,
+			debug);
+
+	devtree = find_devtree(filename);
+	if (!devtree)
+		return EINVAL;
+
+	/*
+	 * Always search the device-tree to find the capable nic devices.
+	 */
+	error = loop_devs(devtree);
+	if (error)
+		return error;
+
+	dev_count = find_file(filename);
+	if (dev_count < 1)
+		error = ENODEV;
+	else {
+		if (debug)
+			printf("%s:\n%s\n\n", filename, bootpath_val);
+		/*
+		 * We find *almost* everything we need in the
+		 * bootpath, save the mac-address.
+		 */
 
+		if (strstr(bootpath_val, "iscsi")) {
+			ofwdevs[0] = calloc(1, sizeof(struct ofw_dev));
+			if (!ofwdevs[0])
+				return ENOMEM;
+
+			error = parse_params(bootpath_val, ofwdevs[0]);
+			if (!error)
+				error = locate_mac(devtree, ofwdevs[0]);
+
+		} else
+			/*
+			 * yikes! we did not boot from iscsi.
+			 * tsk, tsk.
+			 */
+			error = EINVAL;
+
+		if (!error) {
+			context = calloc(1, sizeof(*context));
+			if (!context)
+				error = ENOMEM;	
+			else {
+				fill_context(context, ofwdevs[0]);
+				list_add_tail(&context->list, list);
+			}
+		}
 	}
 
 	return error;
diff -Naurp open-iscsi-2.0-868-test1.work3/utils/fwparam_ibft/Makefile open-iscsi-2.0-868-test1.work2/utils/fwparam_ibft/Makefile
--- open-iscsi-2.0-868-test1.work3/utils/fwparam_ibft/Makefile	2008-11-30 20:44:12.000000000 -0600
+++ open-iscsi-2.0-868-test1.work2/utils/fwparam_ibft/Makefile	2008-11-30 20:43:24.000000000 -0600
@@ -21,7 +21,7 @@
 #	    "Prasanna Mumbai" <mumbai.prasanna@gmail.com>
 #
 
-OBJS := fwparam_ibft.o fw_entry.o fwparam_ibft_sysfs.o
+OBJS := fw_entry.o fwparam_ibft_sysfs.o
 OBJS += prom_lex.o prom_parse.tab.o fwparam_ppc.o
 GENFILES := prom_lex.c prom_parse.tab.c prom_parse.tab.h
 LIB=libfwparam.a
