/*
 *  Copyright 2007 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:
 *
 *  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>

#define IBFT_ISCSI_VERSION "0.4.9"
#define IBFT_ISCSI_DATE "2008-Mar-14"

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 ibft_table_header *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, NIPQUAD_FMT, ip[12],
			       ip[13], ip[14], ip[15]);
	} else {
		/*
		 * IPv6
		 */
		str += sprintf(str, NIP6_FMT, ntohs(ip[0]), ntohs(ip[1]),
			       ntohs(ip[2]), ntohs(ip[3]), ntohs(ip[4]),
			       ntohs(ip[5]), ntohs(ip[6]), ntohs(ip[7]));
	}
	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;
	char *mac;
	int 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 = ~((1 << (32-nic->subnet_mask_prefix))-1);
		str += sprintf(str, NIPQUAD_FMT,
			       (u8)(val >> 24), (u8)(val >> 16),
			       (u8)(val >> 8), (u8)(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:
		mac = nic->mac;
		str += sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x\n",
			       (u8)mac[0], (u8)mac[1], (u8)mac[2],
			       (u8)mac[3], (u8)mac[4], (u8)mac[5]);
		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 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->length;

	/* Sanity checking of iBFT. */
	if (ibft_addr->revision != 1) {
		printk(KERN_ERR "iBFT module supports only revision 1, " \
				"while this is %d.\n", ibft_addr->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 ibft_table_header *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->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 ibft_table_header *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->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->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->attr.owner = THIS_MODULE;

	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->dhcp, nulls, sizeof(nic->dhcp)))
			rc = 1;
		break;
	case ibft_eth_subnet_mask:
		if (!memcmp(nic->dhcp, nulls, sizeof(nic->dhcp)))
			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%lx.\n",
		       virt_to_phys((void *)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);
