diff -Naurp open-iscsi-2.0-870-rc1/utils/fwparam_ibft/fw_entry.c open-iscsi-2.0-870-rc1.work/utils/fwparam_ibft/fw_entry.c --- open-iscsi-2.0-870-rc1/utils/fwparam_ibft/fw_entry.c 2008-06-30 20:14:03.000000000 -0500 +++ open-iscsi-2.0-870-rc1.work/utils/fwparam_ibft/fw_entry.c 2008-06-30 21:21:57.000000000 -0500 @@ -29,7 +29,8 @@ int fw_get_entry(struct boot_context *co ret = fwparam_ppc(context, filepath); if (ret) - ret = fwparam_ibft(context, filepath); + ret = fwparam_ibft_sysfs(context, filepath); + return ret; } diff -Naurp open-iscsi-2.0-870-rc1/utils/fwparam_ibft/fwparam_ibft.h open-iscsi-2.0-870-rc1.work/utils/fwparam_ibft/fwparam_ibft.h --- open-iscsi-2.0-870-rc1/utils/fwparam_ibft/fwparam_ibft.h 2008-06-30 20:14:03.000000000 -0500 +++ open-iscsi-2.0-870-rc1.work/utils/fwparam_ibft/fwparam_ibft.h 2008-06-30 21:21:57.000000000 -0500 @@ -153,6 +153,7 @@ extern int dev_count; #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-870-rc1/utils/fwparam_ibft/fwparam_ibft_sysfs.c open-iscsi-2.0-870-rc1.work/utils/fwparam_ibft/fwparam_ibft_sysfs.c --- open-iscsi-2.0-870-rc1/utils/fwparam_ibft/fwparam_ibft_sysfs.c 1969-12-31 18:00:00.000000000 -0600 +++ open-iscsi-2.0-870-rc1.work/utils/fwparam_ibft/fwparam_ibft_sysfs.c 2008-06-30 21:21:57.000000000 -0500 @@ -0,0 +1,271 @@ +/* + * Copyright (C) IBM Corporation. 2007 + * Author: Konrad Rzeszutek + * + * 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, see . + */ + +#define _XOPEN_SOURCE 500 +#include +#include +#include +#include +#include +#include +#include +#include "fwparam_ibft.h" +#include + +#define IBFT_MAX 255 +#define IBFT_SYSFS_ROOT "/sys/firmware/ibft/" + +static char *target_list[IBFT_MAX]; +static char *nic_list[IBFT_MAX]; +static int nic_cnt; +static int tgt_cnt; + +/* + * Helper routines. + */ +static int file_exist(const char *file) +{ + + struct stat bootpath_stat; + + return !stat(file, &bootpath_stat); +} + +static int read_file(const char *file, char **contents) +{ + int error, fd, bytes_read; + struct stat bootpath_stat; + + error = stat(file, &bootpath_stat); + if (error < 0) { + fprintf(stderr, "(%s:%d) stat %s, %s\n", __FILE__, __LINE__, + file, strerror(errno)); + return error; + } + + *contents = malloc(bootpath_stat.st_size); + if (!*contents) { + error = ENOMEM; + fprintf(stderr, "(%s:%d) Could not allocate enough memory for "\ + "%s: %s (%d)\n", + __FILE__, __LINE__, file, strerror(error), error); + return errno; + } + + fd = open(file, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "(%s:%d): Could not open %s: %s (%d)\n", + __FILE__, __LINE__, file, strerror(errno), errno); + free(*contents); + return errno; + } + + bytes_read = read(fd, *contents, bootpath_stat.st_size); + close(fd); + if (bytes_read > bootpath_stat.st_size) { + fprintf(stderr, "(%s:%d) Read more data in than expected for "\ + "%s: %s (%d)\n", + __FILE__, __LINE__, file, strerror(EIO), EIO); + free(*contents); + return errno; + } + /* chop() implementation */ + if (*(*contents + (ssize_t)(bytes_read - 1)) == '\n') + *(*contents + (ssize_t) (bytes_read - 1)) = 0; + + return 0; +} + +static int read_data(const char *dir, const char *name, char *dst, ssize_t size) +{ + char *data = NULL; + char file[FILENAMESZ]; + int rc = 0; + + memset(file, 0, FILENAMESZ); + strncat(file, dir, FILENAMESZ); + strncat(file, name, FILENAMESZ); + + 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); + } + + return rc; +} + +static int read_int_data(const char *dir, const char *name, int *dst) +{ + int rc = 0; + char contents[5]; /* The flag is a 1 byte value */ + + rc = read_data(dir, name, (char *)&contents, sizeof(contents)); + if (!rc) + *dst = atoi(contents); + + return rc; +} + +/* + * Finds the etherrnetX and targetX under the sysfs directory. + */ +static int find_sysfs_dirs(const char *fpath, const struct stat *sb, + int tflag, struct FTW *ftw) +{ + if (tflag == FTW_D && + (strstr(fpath + ftw->base, "target"))) + target_list[tgt_cnt++] = strdup(fpath); + + if (tflag == FTW_D && + (strstr(fpath + ftw->base, "ethernet"))) + nic_list[nic_cnt++] = strdup(fpath); + + return 0; +} + +/* + * Routines to fill in the context values. + */ +static int fill_nic_context(const char *dir, struct boot_context *context) +{ + int rc = 0; + + rc |= read_data(dir, "/mac", context->mac, sizeof(context->mac)); + rc |= read_data(dir, "/vlan", context->vlan, sizeof(context->vlan)); + rc |= read_data(dir, "/ip-addr", context->ipaddr, + sizeof(context->ipaddr)); + rc |= read_data(dir, "/mask", context->mask, sizeof(context->mask)); + + return rc; +} + +static int fill_initiator_context(const char *dir, struct boot_context *context) +{ + int rc = 0; + + rc |= read_data(dir, "/initiator-name", context->initiatorname, + sizeof(context->initiatorname)); + rc |= read_data(dir, "/isns-server", context->isid, + sizeof(context->isid)); + + return rc; +} +static int fill_tgt_context(const char *dir, struct boot_context *context) +{ + int rc = 0; + + rc |= read_data(dir, "/target-name", context->targetname, + sizeof(context->targetname)); + rc |= read_data(dir, "/ip-addr", context->target_ipaddr, + sizeof(context->target_ipaddr)); + rc |= read_int_data(dir, "/port", &context->target_port); + rc |= read_data(dir, "/lun", context->lun, + sizeof(context->lun)); + rc |= read_data(dir, "/chap-name", context->chap_name, + sizeof(context->chap_name)); + rc |= read_data(dir, "/chap-secret", context->chap_password, + sizeof(context->chap_password)); + rc |= read_data(dir, "/rev-chap-name", context->chap_name_in, + sizeof(context->chap_name_in)); + rc |= read_data(dir, "/rev-chap-name-secret", context->chap_password_in, + sizeof(context->chap_password_in)); + + return 0; +} + +#define IBFT_SYSFS_FLAG_NAME "/flags" +#define IBFT_SYSFS_FLAG_FW_SEL_BOOT 2 + +static int find_boot_flag(char *list[], ssize_t size, int *boot_idx) +{ + int rc = -1; + int i, flag = -1; + + for (i = 0; i < size; i++, flag = -1) { + rc = read_int_data(list[i], IBFT_SYSFS_FLAG_NAME, &flag); + if (flag & IBFT_SYSFS_FLAG_FW_SEL_BOOT) { + *boot_idx = i; + rc = 0; + break; + } + + } + + return rc; +} + +static void deallocate_lists(void) +{ + int i; + + for (i = 0; i < nic_cnt; i++) + free(nic_list[i]); + + nic_cnt = 0; + for (i = 0; i < tgt_cnt; i++) + free(target_list[i]); + + tgt_cnt = 0; + +} + +int fwparam_ibft_sysfs(struct boot_context *context, const char *filepath) +{ + char initiator_dir[FILENAMESZ]; + char *root_sysfs = NULL; + int rc = 1; + int nic_idx = -1, tgt_idx = -1; + + if (filepath) + root_sysfs = (char *)filepath; + else + root_sysfs = IBFT_SYSFS_ROOT; + + memset(&initiator_dir, 0 , FILENAMESZ); + strncat(initiator_dir, root_sysfs, FILENAMESZ); + strncat(initiator_dir, "initiator", FILENAMESZ); + + if (file_exist(initiator_dir)) { + + /* Find the target's and the ethernet's */ + rc = nftw(root_sysfs, find_sysfs_dirs, 20, 1); + + /* Find wihch target and which ethernet have + the boot flag set. */ + rc = find_boot_flag(nic_list, nic_cnt, &nic_idx); + if (rc) + goto free; + + rc = find_boot_flag(target_list, tgt_cnt, &tgt_idx); + if (rc) + goto free; + + /* Fill in the context values */ + rc = fill_nic_context(nic_list[nic_idx], context); + rc |= fill_tgt_context(target_list[tgt_idx], context); + rc |= fill_initiator_context(initiator_dir, context); + } +free: + deallocate_lists(); + return rc; +} diff -Naurp open-iscsi-2.0-870-rc1/utils/fwparam_ibft/Makefile open-iscsi-2.0-870-rc1.work/utils/fwparam_ibft/Makefile --- open-iscsi-2.0-870-rc1/utils/fwparam_ibft/Makefile 2008-06-30 20:14:03.000000000 -0500 +++ open-iscsi-2.0-870-rc1.work/utils/fwparam_ibft/Makefile 2008-06-30 21:22:44.000000000 -0500 @@ -22,7 +22,7 @@ # OBJS := fwparam_ibft.o fw_entry.o -OBJS += prom_lex.o prom_parse.tab.o fwparam_ppc.o +OBJS += prom_lex.o prom_parse.tab.o fwparam_ppc.o fwparam_ibft_sysfs.o CLEANFILES = $(OBJS) *.output *~ OPTFLAGS ?= -O2 -g -fPIC