/*
 * Copyright (C) 2012 CERN (www.cern.ch)
 * Author: Alessandro Rubini <rubini@gnudd.com>
 *
 * Released according to the GNU GPL, version 2 or any later version.
 *
 * This work is part of the White Rabbit project, a research effort led
 * by CERN, the European Institute for Nuclear Research.
 */
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/fmc.h>
#include <linux/ipmi-fru.h>

/* The fru parser is both user and kernel capable: it needs alloc */
void *fru_alloc(size_t size)
{
	return kzalloc(size, GFP_KERNEL);
}

/* The actual match function */
int fmc_match(struct device *dev, struct device_driver *drv)
{
	struct fmc_driver *fdrv = to_fmc_driver(drv);
	struct fmc_device *fdev = to_fmc_device(dev);
	struct fmc_fru_id *fid;
	int i, matched = 0;

	/* This currently only matches the EEPROM (FRU id) */
	fid = fdrv->id_table.fru_id;
	if (!fid) {
		dev_warn(&fdev->dev, "Driver has no ID: matches all\n");
		matched = 1;
	} else {
		if (!fdev->id.manufacturer || !fdev->id.product_name)
			return 0; /* the device has no FRU information */
		for (i = 0; i < fdrv->id_table.fru_id_nr; i++, fid++) {
			if (fid->manufacturer &&
			    strcmp(fid->manufacturer, fdev->id.manufacturer))
				continue;
			if (fid->product_name &&
			    strcmp(fid->product_name, fdev->id.product_name))
				continue;
			matched = 1;
			break;
		}
	}

	/* FIXME: match SDB contents */
	return matched;
}

/* This function creates ID info for a newly registered device */
int fmc_fill_id_info(struct fmc_device *fmc)
{
	struct fru_common_header *h;
	struct fru_board_info_area *bia;
	int ret, allocated = 0;

	/* If we know the eeprom length, try to read it off the device */
	if (fmc->eeprom_len && !fmc->eeprom) {
		fmc->eeprom = kzalloc(fmc->eeprom_len, GFP_KERNEL);
		if (!fmc->eeprom)
			return -ENOMEM;
		allocated = 1;
		ret = fmc->op->read_ee(fmc, 0, fmc->eeprom, fmc->eeprom_len);
		if (ret < 0)
			goto out;
	}

	/* If no eeprom, continue with other matches */
	if (!fmc->eeprom)
		return 0;

	dev_info(fmc->hwdev, "mezzanine %i\n", fmc->slot_id); /* header */

	/* So we have the eeprom: parse the FRU part (if any) */
	h = (void *)fmc->eeprom;
	if (h->format != 1) {
		pr_info("      EEPROM has no FRU information\n");
		goto out;
	}
	if (!fru_header_cksum_ok(h)) {
		pr_info("      FRU: wrong header checksum\n");
		goto out;
	}
	bia = fru_get_board_area(h);
	if (!fru_bia_cksum_ok(bia)) {
		pr_info("      FRU: wrong board area checksum\n");
		goto out;
	}
	fmc->id.manufacturer = fru_get_board_manufacturer(h);
	fmc->id.product_name = fru_get_product_name(h);
	pr_info("      Manufacturer: %s\n", fmc->id.manufacturer);
	pr_info("      Product name: %s\n", fmc->id.product_name);

	/* Create the short name (FIXME: look in sdb as well) */
	fmc->mezzanine_name = kstrdup(fmc->id.product_name, GFP_KERNEL);

out:
	if (allocated) {
		kfree(fmc->eeprom);
		fmc->eeprom = NULL;
	}
	return 0; /* no error: let other identification work */
}

/* Some ID data is allocated using fru_alloc() above, so release it */
void fmc_free_id_info(struct fmc_device *fmc)
{
	kfree(fmc->mezzanine_name);
	kfree(fmc->id.manufacturer);
	kfree(fmc->id.product_name);
}
