/*
 *  Copyright 2007-2010 Red Hat, Inc.
 *  by Peter Jones <pjones@redhat.com>
 *  Copyright 2008 IBM, Inc.
 *  by Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
 *  Copyright 2008
 *  by Konrad Rzeszutek <ketuzsezr@darnok.org>
 *
 * This code exposes the iSCSI Boot Format Table to userland via sysfs.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License v2.0 as published by
 * the Free Software Foundation
 *
 * 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.
 *
 * Changelog:
 *
 *  06 Jan 2010 - Peter Jones <pjones@redhat.com>
 *    New changelog entries are in the git log from now on.  Not here.
 *
 *  14 Mar 2008 - Konrad Rzeszutek <ketuzsezr@darnok.org>
 *    Updated comments and copyrights. (v0.4.9)
 *
 *  11 Feb 2008 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
 *    Converted to using ibft_addr. (v0.4.8)
 *
 *   8 Feb 2008 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
 *    Combined two functions in one: reserve_ibft_region. (v0.4.7)
 *
 *  30 Jan 2008 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
 *   Added logic to handle IPv6 addresses. (v0.4.6)
 *
 *  25 Jan 2008 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
 *   Added logic to handle badly not-to-spec iBFT. (v0.4.5)
 *
 *   4 Jan 2008 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
 *   Added __init to function declarations. (v0.4.4)
 *
 *  21 Dec 2007 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
 *   Updated kobject registration, combined unregister functions in one
 *   and code and style cleanup. (v0.4.3)
 *
 *   5 Dec 2007 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
 *   Added end-markers to enums and re-organized kobject registration. (v0.4.2)
 *
 *   4 Dec 2007 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
 *   Created 'device' sysfs link to the NIC and style cleanup. (v0.4.1)
 *
 *  28 Nov 2007 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
 *   Added sysfs-ibft documentation, moved 'find_ibft' function to
 *   in its own file and added text attributes for every struct field.  (v0.4)
 *
 *  21 Nov 2007 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
 *   Added text attributes emulating OpenFirmware /proc/device-tree naming.
 *   Removed binary /sysfs interface (v0.3)
 *
 *  29 Aug 2007 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
 *   Added functionality in setup.c to reserve iBFT region. (v0.2)
 *
 *  27 Aug 2007 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
 *   First version exposing iBFT data via a binary /sysfs. (v0.1)
 *
 */


#include <linux/blkdev.h>
#include <linux/capability.h>
#include <linux/ctype.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/iscsi_ibft.h>
#include <linux/limits.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/acpi.h>

#define IBFT_ISCSI_VERSION "0.5.0"
#define IBFT_ISCSI_DATE "2010-Feb-25"

MODULE_AUTHOR("Peter Jones <pjones@redhat.com> and \
Konrad Rzeszutek <ketuzsezr@darnok.org>");
MODULE_DESCRIPTION("sysfs interface to BIOS iBFT information");
MODULE_LICENSE("GPL");
MODULE_VERSION(IBFT_ISCSI_VERSION);

struct ibft_hdr {
	u8 id;
	u8 version;
	u16 length;
	u8 index;
	u8 flags;
} __attribute__((__packed__));

struct ibft_control {
	struct ibft_hdr hdr;
	u16 extensions;
	u16 initiator_off;
	u16 nic0_off;
	u16 tgt0_off;
	u16 nic1_off;
	u16 tgt1_off;
} __attribute__((__packed__));

struct ibft_initiator {
	struct ibft_hdr hdr;
	char isns_server[16];
	char slp_server[16];
	char pri_radius_server[16];
	char sec_radius_server[16];
	u16 initiator_name_len;
	u16 initiator_name_off;
} __attribute__((__packed__));

struct ibft_nic {
	struct ibft_hdr hdr;
	char ip_addr[16];
	u8 subnet_mask_prefix;
	u8 origin;
	char gateway[16];
	char primary_dns[16];
	char secondary_dns[16];
	char dhcp[16];
	u16 vlan;
	char mac[6];
	u16 pci_bdf;
	u16 hostname_len;
	u16 hostname_off;
} __attribute__((__packed__));

struct ibft_tgt {
	struct ibft_hdr hdr;
	char ip_addr[16];
	u16 port;
	char lun[8];
	u8 chap_type;
	u8 nic_assoc;
	u16 tgt_name_len;
	u16 tgt_name_off;
	u16 chap_name_len;
	u16 chap_name_off;
	u16 chap_secret_len;
	u16 chap_secret_off;
	u16 rev_chap_name_len;
	u16 rev_chap_name_off;
	u16 rev_chap_secret_len;
	u16 rev_chap_secret_off;
} __attribute__((__packed__));

/*
 * The kobject different types and its names.
 *
*/
enum ibft_id {
	id_reserved = 0, /* We don't support. */
	id_control = 1, /* Should show up only once and is not exported. */
	id_initiator = 2,
	id_nic = 3,
	id_target = 4,
	id_extensions = 5, /* We don't support. */
	id_end_marker,
};

/*
 * We do not support the other types, hence the usage of NULL.
 * This maps to the enum ibft_id.
 */
static const char *ibft_id_names[] =
	{NULL, NULL, "initiator", "ethernet%d", "target%d", NULL, NULL};

/*
 * The text attributes names for each of the kobjects.
*/
enum ibft_eth_properties_enum {
	ibft_eth_index,
	ibft_eth_flags,
	ibft_eth_ip_addr,
	ibft_eth_subnet_mask,
	ibft_eth_origin,
	ibft_eth_gateway,
	ibft_eth_primary_dns,
	ibft_eth_secondary_dns,
	ibft_eth_dhcp,
	ibft_eth_vlan,
	ibft_eth_mac,
	/* ibft_eth_pci_bdf - this is replaced by link to the device itself. */
	ibft_eth_hostname,
	ibft_eth_end_marker,
};

static const char *ibft_eth_properties[] =
	{"index", "flags", "ip-addr", "subnet-mask", "origin", "gateway",
	"primary-dns", "secondary-dns", "dhcp", "vlan", "mac", "hostname",
	NULL};

enum ibft_tgt_properties_enum {
	ibft_tgt_index,
	ibft_tgt_flags,
	ibft_tgt_ip_addr,
	ibft_tgt_port,
	ibft_tgt_lun,
	ibft_tgt_chap_type,
	ibft_tgt_nic_assoc,
	ibft_tgt_name,
	ibft_tgt_chap_name,
	ibft_tgt_chap_secret,
	ibft_tgt_rev_chap_name,
	ibft_tgt_rev_chap_secret,
	ibft_tgt_end_marker,
};

static const char *ibft_tgt_properties[] =
	{"index", "flags", "ip-addr", "port", "lun", "chap-type", "nic-assoc",
	"target-name", "chap-name", "chap-secret", "rev-chap-name",
	"rev-chap-name-secret", NULL};

enum ibft_initiator_properties_enum {
	ibft_init_index,
	ibft_init_flags,
	ibft_init_isns_server,
	ibft_init_slp_server,
	ibft_init_pri_radius_server,
	ibft_init_sec_radius_server,
	ibft_init_initiator_name,
	ibft_init_end_marker,
};

static const char *ibft_initiator_properties[] =
	{"index", "flags", "isns-server", "slp-server", "pri-radius-server",
	"sec-radius-server", "initiator-name", NULL};

/*
 * The kobject and attribute structures.
 */

struct ibft_kobject {
	struct acpi_table_ibft *header;
	union {
		struct ibft_initiator *initiator;
		struct ibft_nic *nic;
		struct ibft_tgt *tgt;
		struct ibft_hdr *hdr;
	};
	struct kobject kobj;
	struct list_head node;
};

struct ibft_attribute {
	struct attribute attr;
	ssize_t (*show) (struct  ibft_kobject *entry,
			 struct ibft_attribute *attr, char *buf);
	union {
		struct ibft_initiator *initiator;
		struct ibft_nic *nic;
		struct ibft_tgt *tgt;
		struct ibft_hdr *hdr;
	};
	struct kobject *kobj;
	int type; /* The enum of the type. This can be any value of:
		ibft_eth_properties_enum, ibft_tgt_properties_enum,
		or ibft_initiator_properties_enum. */
	struct list_head node;
};

static LIST_HEAD(ibft_attr_list);
static LIST_HEAD(ibft_kobject_list);

static const char nulls[16];

/*
 * Helper functions to parse data properly.
 */
static ssize_t sprintf_ipaddr(char *buf, u8 *ip)
{
	char *str = buf;

	if (ip[0] == 0 && ip[1] == 0 && ip[2] == 0 && ip[3] == 0 &&
	    ip[4] == 0 && ip[5] == 0 && ip[6] == 0 && ip[7] == 0 &&
	    ip[8] == 0 && ip[9] == 0 && ip[10] == 0xff && ip[11] == 0xff) {
		/*
		 * IPV4
		 */
		str += sprintf(buf, "%pI4", ip + 12);
	} else {
		/*
		 * IPv6
		 */
		str += sprintf(str, "%pI6", ip);
	}
	str += sprintf(str, "\n");
	return str - buf;
}

static ssize_t sprintf_string(char *str, int len, char *buf)
{
	return sprintf(str, "%.*s\n", len, buf);
}

/*
 * Helper function to verify the IBFT header.
 */
static int ibft_verify_hdr(char *t, struct ibft_hdr *hdr, int id, int length)
{
	if (hdr->id != id) {
		printk(KERN_ERR "iBFT error: We expected the " \
				"field header.id to have %d but " \
				"found %d instead!\n", id, hdr->id);
		return -ENODEV;
	}
	if (hdr->length != length) {
		printk(KERN_ERR "iBFT error: We expected the " \
				"field header.length to have %d but " \
				"found %d instead!\n", length, hdr->length);
		return -ENODEV;
	}

	return 0;
}

static void ibft_release(struct kobject *kobj)
{
	struct ibft_kobject *ibft =
		container_of(kobj, struct ibft_kobject, kobj);
	kfree(ibft);
}

/*
 *  Routines for parsing the iBFT data to be human readable.
 */
static ssize_t ibft_attr_show_initiator(struct ibft_kobject *entry,
					struct ibft_attribute *attr,
					char *buf)
{
	struct ibft_initiator *initiator = entry->initiator;
	void *ibft_loc = entry->header;
	char *str = buf;

	if (!initiator)
		return 0;

	switch (attr->type) {
	case ibft_init_index:
		str += sprintf(str, "%d\n", initiator->hdr.index);
		break;
	case ibft_init_flags:
		str += sprintf(str, "%d\n", initiator->hdr.flags);
		break;
	case ibft_init_isns_server:
		str += sprintf_ipaddr(str, initiator->isns_server);
		break;
	case ibft_init_slp_server:
		str += sprintf_ipaddr(str, initiator->slp_server);
		break;
	case ibft_init_pri_radius_server:
		str += sprintf_ipaddr(str, initiator->pri_radius_server);
		break;
	case ibft_init_sec_radius_server:
		str += sprintf_ipaddr(str, initiator->sec_radius_server);
		break;
	case ibft_init_initiator_name:
		str += sprintf_string(str, initiator->initiator_name_len,
				      (char *)ibft_loc +
				      initiator->initiator_name_off);
		break;
	default:
		break;
	}

	return str - buf;
}

static ssize_t ibft_attr_show_nic(struct ibft_kobject *entry,
				  struct ibft_attribute *attr,
				  char *buf)
{
	struct ibft_nic *nic = entry->nic;
	void *ibft_loc = entry->header;
	char *str = buf;
	__be32 val;

	if (!nic)
		return 0;

	switch (attr->type) {
	case ibft_eth_index:
		str += sprintf(str, "%d\n", nic->hdr.index);
		break;
	case ibft_eth_flags:
		str += sprintf(str, "%d\n", nic->hdr.flags);
		break;
	case ibft_eth_ip_addr:
		str += sprintf_ipaddr(str, nic->ip_addr);
		break;
	case ibft_eth_subnet_mask:
		val = cpu_to_be32(~((1 << (32-nic->subnet_mask_prefix))-1));
		str += sprintf(str, "%pI4", &val);
		break;
	case ibft_eth_origin:
		str += sprintf(str, "%d\n", nic->origin);
		break;
	case ibft_eth_gateway:
		str += sprintf_ipaddr(str, nic->gateway);
		break;
	case ibft_eth_primary_dns:
		str += sprintf_ipaddr(str, nic->primary_dns);
		break;
	case ibft_eth_secondary_dns:
		str += sprintf_ipaddr(str, nic->secondary_dns);
		break;
	case ibft_eth_dhcp:
		str += sprintf_ipaddr(str, nic->dhcp);
		break;
	case ibft_eth_vlan:
		str += sprintf(str, "%d\n", nic->vlan);
		break;
	case ibft_eth_mac:
		str += sprintf(str, "%pM\n", nic->mac);
		break;
	case ibft_eth_hostname:
		str += sprintf_string(str, nic->hostname_len,
				      (char *)ibft_loc + nic->hostname_off);
		break;
	default:
		break;
	}

	return str - buf;
};

static ssize_t ibft_attr_show_target(struct ibft_kobject *entry,
				     struct ibft_attribute *attr,
				     char *buf)
{
	struct ibft_tgt *tgt = entry->tgt;
	void *ibft_loc = entry->header;
	char *str = buf;
	int i;

	if (!tgt)
		return 0;

	switch (attr->type) {
	case ibft_tgt_index:
		str += sprintf(str, "%d\n", tgt->hdr.index);
		break;
	case ibft_tgt_flags:
		str += sprintf(str, "%d\n", tgt->hdr.flags);
		break;
	case ibft_tgt_ip_addr:
		str += sprintf_ipaddr(str, tgt->ip_addr);
		break;
	case ibft_tgt_port:
		str += sprintf(str, "%d\n", tgt->port);
		break;
	case ibft_tgt_lun:
		for (i = 0; i < 8; i++)
			str += sprintf(str, "%x", (u8)tgt->lun[i]);
		str += sprintf(str, "\n");
		break;
	case ibft_tgt_nic_assoc:
		str += sprintf(str, "%d\n", tgt->nic_assoc);
		break;
	case ibft_tgt_chap_type:
		str += sprintf(str, "%d\n", tgt->chap_type);
		break;
	case ibft_tgt_name:
		str += sprintf_string(str, tgt->tgt_name_len,
				      (char *)ibft_loc + tgt->tgt_name_off);
		break;
	case ibft_tgt_chap_name:
		str += sprintf_string(str, tgt->chap_name_len,
				      (char *)ibft_loc + tgt->chap_name_off);
		break;
	case ibft_tgt_chap_secret:
		str += sprintf_string(str, tgt->chap_secret_len,
				      (char *)ibft_loc + tgt->chap_secret_off);
		break;
	case ibft_tgt_rev_chap_name:
		str += sprintf_string(str, tgt->rev_chap_name_len,
				      (char *)ibft_loc +
				      tgt->rev_chap_name_off);
		break;
	case ibft_tgt_rev_chap_secret:
		str += sprintf_string(str, tgt->rev_chap_secret_len,
				      (char *)ibft_loc +
				      tgt->rev_chap_secret_off);
		break;
	default:
		break;
	}

	return str - buf;
}

/*
 * The routine called for all sysfs attributes.
 */
static ssize_t ibft_show_attribute(struct kobject *kobj,
				    struct attribute *attr,
				    char *buf)
{
	struct ibft_kobject *dev =
		container_of(kobj, struct ibft_kobject, kobj);
	struct ibft_attribute *ibft_attr =
		container_of(attr, struct ibft_attribute, attr);
	ssize_t ret = -EIO;
	char *str = buf;

	if (!capable(CAP_SYS_ADMIN))
		return -EACCES;

	if (ibft_attr->show)
		ret = ibft_attr->show(dev, ibft_attr, str);

	return ret;
}

static const struct sysfs_ops ibft_attr_ops = {
	.show = ibft_show_attribute,
};

static struct kobj_type ibft_ktype = {
	.release = ibft_release,
	.sysfs_ops = &ibft_attr_ops,
};

static struct kset *ibft_kset;

static int __init ibft_check_device(void)
{
	int len;
	u8 *pos;
	u8 csum = 0;

	len = ibft_addr->header.length;

	/* Sanity checking of iBFT. */
	if (ibft_addr->header.revision != 1) {
		printk(KERN_ERR "iBFT module supports only revision 1, " \
				"while this is %d.\n",
				ibft_addr->header.revision);
		return -ENOENT;
	}
	for (pos = (u8 *)ibft_addr; pos < (u8 *)ibft_addr + len; pos++)
		csum += *pos;

	if (csum) {
		printk(KERN_ERR "iBFT has incorrect checksum (0x%x)!\n", csum);
		return -ENOENT;
	}

	return 0;
}

/*
 * Helper function for ibft_register_kobjects.
 */
static int __init ibft_create_kobject(struct acpi_table_ibft *header,
				       struct ibft_hdr *hdr,
				       struct list_head *list)
{
	struct ibft_kobject *ibft_kobj = NULL;
	struct ibft_nic *nic = (struct ibft_nic *)hdr;
	struct pci_dev *pci_dev;
	int rc = 0;

	ibft_kobj = kzalloc(sizeof(*ibft_kobj), GFP_KERNEL);
	if (!ibft_kobj)
		return -ENOMEM;

	ibft_kobj->header = header;
	ibft_kobj->hdr = hdr;

	switch (hdr->id) {
	case id_initiator:
		rc = ibft_verify_hdr("initiator", hdr, id_initiator,
				     sizeof(*ibft_kobj->initiator));
		break;
	case id_nic:
		rc = ibft_verify_hdr("ethernet", hdr, id_nic,
				     sizeof(*ibft_kobj->nic));
		break;
	case id_target:
		rc = ibft_verify_hdr("target", hdr, id_target,
				     sizeof(*ibft_kobj->tgt));
		break;
	case id_reserved:
	case id_control:
	case id_extensions:
		/* Fields which we don't support. Ignore them */
		rc = 1;
		break;
	default:
		printk(KERN_ERR "iBFT has unknown structure type (%d). " \
				"Report this bug to %.6s!\n", hdr->id,
				header->header.oem_id);
		rc = 1;
		break;
	}

	if (rc) {
		/* Skip adding this kobject, but exit with non-fatal error. */
		kfree(ibft_kobj);
		goto out_invalid_struct;
	}

	ibft_kobj->kobj.kset = ibft_kset;

	rc = kobject_init_and_add(&ibft_kobj->kobj, &ibft_ktype,
				  NULL, ibft_id_names[hdr->id], hdr->index);

	if (rc) {
		kfree(ibft_kobj);
		goto out;
	}

	kobject_uevent(&ibft_kobj->kobj, KOBJ_ADD);

	if (hdr->id == id_nic) {
		/*
		* We don't search for the device in other domains than
		* zero. This is because on x86 platforms the BIOS
		* executes only devices which are in domain 0. Furthermore, the
		* iBFT spec doesn't have a domain id field :-(
		*/
		pci_dev = pci_get_bus_and_slot((nic->pci_bdf & 0xff00) >> 8,
					       (nic->pci_bdf & 0xff));
		if (pci_dev) {
			rc = sysfs_create_link(&ibft_kobj->kobj,
					       &pci_dev->dev.kobj, "device");
			pci_dev_put(pci_dev);
		}
	}

	/* Nothing broke so lets add it to the list. */
	list_add_tail(&ibft_kobj->node, list);
out:
	return rc;
out_invalid_struct:
	/* Unsupported structs are skipped. */
	return 0;
}

/*
 * Scan the IBFT table structure for the NIC and Target fields. When
 * found add them on the passed-in list. We do not support the other
 * fields at this point, so they are skipped.
 */
static int __init ibft_register_kobjects(struct acpi_table_ibft *header,
					  struct list_head *list)
{
	struct ibft_control *control = NULL;
	void *ptr, *end;
	int rc = 0;
	u16 offset;
	u16 eot_offset;

	control = (void *)header + sizeof(*header);
	end = (void *)control + control->hdr.length;
	eot_offset = (void *)header + header->header.length - (void *)control;
	rc = ibft_verify_hdr("control", (struct ibft_hdr *)control, id_control,
			     sizeof(*control));

	/* iBFT table safety checking */
	rc |= ((control->hdr.index) ? -ENODEV : 0);
	if (rc) {
		printk(KERN_ERR "iBFT error: Control header is invalid!\n");
		return rc;
	}
	for (ptr = &control->initiator_off; ptr < end; ptr += sizeof(u16)) {
		offset = *(u16 *)ptr;
		if (offset && offset < header->header.length &&
						offset < eot_offset) {
			rc = ibft_create_kobject(header,
						 (void *)header + offset,
						 list);
			if (rc)
				break;
		}
	}

	return rc;
}

static void ibft_unregister(struct list_head *attr_list,
			     struct list_head *kobj_list)
{
	struct ibft_kobject *data = NULL, *n;
	struct ibft_attribute *attr = NULL, *m;

	list_for_each_entry_safe(attr, m, attr_list, node) {
		sysfs_remove_file(attr->kobj, &attr->attr);
		list_del(&attr->node);
		kfree(attr);
	};
	list_del_init(attr_list);

	list_for_each_entry_safe(data, n, kobj_list, node) {
		list_del(&data->node);
		if (data->hdr->id == id_nic)
			sysfs_remove_link(&data->kobj, "device");
		kobject_put(&data->kobj);
	};
	list_del_init(kobj_list);
}

static int __init ibft_create_attribute(struct ibft_kobject *kobj_data,
					 int type,
					 const char *name,
					 ssize_t (*show)(struct ibft_kobject *,
							 struct ibft_attribute*,
							 char *buf),
					 struct list_head *list)
{
	struct ibft_attribute *attr = NULL;
	struct ibft_hdr *hdr = kobj_data->hdr;

	attr = kmalloc(sizeof(*attr), GFP_KERNEL);
	if (!attr)
		return -ENOMEM;

	attr->attr.name = name;
	attr->attr.mode = S_IRUSR;

	attr->hdr = hdr;
	attr->show = show;
	attr->kobj = &kobj_data->kobj;
	attr->type = type;

	list_add_tail(&attr->node, list);

	return 0;
}

/*
 * Helper routiners to check to determine if the entry is valid
 * in the proper iBFT structure.
 */
static int __init ibft_check_nic_for(struct ibft_nic *nic, int entry)
{
	int rc = 0;

	switch (entry) {
	case ibft_eth_index:
	case ibft_eth_flags:
		rc = 1;
		break;
	case ibft_eth_ip_addr:
		if (memcmp(nic->ip_addr, nulls, sizeof(nic->ip_addr)))
			rc = 1;
		break;
	case ibft_eth_subnet_mask:
		if (nic->subnet_mask_prefix)
			rc = 1;
		break;
	case ibft_eth_origin:
		rc = 1;
		break;
	case ibft_eth_gateway:
		if (memcmp(nic->gateway, nulls, sizeof(nic->gateway)))
			rc = 1;
		break;
	case ibft_eth_primary_dns:
		if (memcmp(nic->primary_dns, nulls,
			   sizeof(nic->primary_dns)))
			rc = 1;
		break;
	case ibft_eth_secondary_dns:
		if (memcmp(nic->secondary_dns, nulls,
			   sizeof(nic->secondary_dns)))
			rc = 1;
		break;
	case ibft_eth_dhcp:
		if (memcmp(nic->dhcp, nulls, sizeof(nic->dhcp)))
			rc = 1;
		break;
	case ibft_eth_vlan:
	case ibft_eth_mac:
		rc = 1;
		break;
	case ibft_eth_hostname:
		if (nic->hostname_off)
			rc = 1;
		break;
	default:
		break;
	}

	return rc;
}

static int __init ibft_check_tgt_for(struct ibft_tgt *tgt, int entry)
{
	int rc = 0;

	switch (entry) {
	case ibft_tgt_index:
	case ibft_tgt_flags:
	case ibft_tgt_ip_addr:
	case ibft_tgt_port:
	case ibft_tgt_lun:
	case ibft_tgt_nic_assoc:
	case ibft_tgt_chap_type:
		rc = 1;
	case ibft_tgt_name:
		if (tgt->tgt_name_len)
			rc = 1;
		break;
	case ibft_tgt_chap_name:
	case ibft_tgt_chap_secret:
		if (tgt->chap_name_len)
			rc = 1;
		break;
	case ibft_tgt_rev_chap_name:
	case ibft_tgt_rev_chap_secret:
		if (tgt->rev_chap_name_len)
			rc = 1;
		break;
	default:
		break;
	}

	return rc;
}

static int __init ibft_check_initiator_for(struct ibft_initiator *init,
					    int entry)
{
	int rc = 0;

	switch (entry) {
	case ibft_init_index:
	case ibft_init_flags:
		rc = 1;
		break;
	case ibft_init_isns_server:
		if (memcmp(init->isns_server, nulls,
			   sizeof(init->isns_server)))
			rc = 1;
		break;
	case ibft_init_slp_server:
		if (memcmp(init->slp_server, nulls,
			   sizeof(init->slp_server)))
			rc = 1;
		break;
	case ibft_init_pri_radius_server:
		if (memcmp(init->pri_radius_server, nulls,
			   sizeof(init->pri_radius_server)))
			rc = 1;
		break;
	case ibft_init_sec_radius_server:
		if (memcmp(init->sec_radius_server, nulls,
			   sizeof(init->sec_radius_server)))
			rc = 1;
		break;
	case ibft_init_initiator_name:
		if (init->initiator_name_len)
			rc = 1;
		break;
	default:
		break;
	}

	return rc;
}

/*
 *  Register the attributes for all of the kobjects.
 */
static int __init ibft_register_attributes(struct list_head *kobject_list,
					    struct list_head *attr_list)
{
	int rc = 0, i = 0;
	struct ibft_kobject *data = NULL;
	struct ibft_attribute *attr = NULL, *m;

	list_for_each_entry(data, kobject_list, node) {
		switch (data->hdr->id) {
		case id_nic:
			for (i = 0; i < ibft_eth_end_marker && !rc; i++)
				if (ibft_check_nic_for(data->nic, i))
					rc = ibft_create_attribute(data, i,
						ibft_eth_properties[i],
						ibft_attr_show_nic, attr_list);
			break;
		case id_target:
			for (i = 0; i < ibft_tgt_end_marker && !rc; i++)
				if (ibft_check_tgt_for(data->tgt, i))
					rc = ibft_create_attribute(data, i,
						ibft_tgt_properties[i],
						ibft_attr_show_target,
						attr_list);
			break;
		case id_initiator:
			for (i = 0; i < ibft_init_end_marker && !rc; i++)
				if (ibft_check_initiator_for(
					data->initiator, i))
					rc = ibft_create_attribute(data, i,
						ibft_initiator_properties[i],
						ibft_attr_show_initiator,
						attr_list);
			break;
		default:
			break;
		}
		if (rc)
			break;
	}
	list_for_each_entry_safe(attr, m, attr_list, node) {
		rc = sysfs_create_file(attr->kobj, &attr->attr);
		if (rc) {
			list_del(&attr->node);
			kfree(attr);
			break;
		}
	}

	return rc;
}

/*
 * ibft_init() - creates sysfs tree entries for the iBFT data.
 */
static int __init ibft_init(void)
{
	int rc = 0;

	ibft_kset = kset_create_and_add("ibft", NULL, firmware_kobj);
	if (!ibft_kset)
		return -ENOMEM;

	if (ibft_addr) {
		printk(KERN_INFO "iBFT detected at 0x%llx.\n",
		       (u64)isa_virt_to_bus(ibft_addr));

		rc = ibft_check_device();
		if (rc)
			goto out_firmware_unregister;

		/* Scan the IBFT for data and register the kobjects. */
		rc = ibft_register_kobjects(ibft_addr, &ibft_kobject_list);
		if (rc)
			goto out_free;

		/* Register the attributes */
		rc = ibft_register_attributes(&ibft_kobject_list,
					      &ibft_attr_list);
		if (rc)
			goto out_free;
	} else
		printk(KERN_INFO "No iBFT detected.\n");

	return 0;

out_free:
	ibft_unregister(&ibft_attr_list, &ibft_kobject_list);
out_firmware_unregister:
	kset_unregister(ibft_kset);
	return rc;
}

static void __exit ibft_exit(void)
{
	ibft_unregister(&ibft_attr_list, &ibft_kobject_list);
	kset_unregister(ibft_kset);
}

module_init(ibft_init);
module_exit(ibft_exit);
