/*
 * Copyright (C) 2010 Piotr Jaroszyński <p.jaroszynski@gmail.com>
 *
 * 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 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, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 */

FILE_LICENCE(GPL2_OR_LATER);

/** @file
 *
 * Linux root_device and root_driver.
 */

#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <ipxe/linux.h>
#include <ipxe/malloc.h>
#include <ipxe/settings.h>

LIST_HEAD(linux_device_requests);
LIST_HEAD(linux_global_settings);

/** Go over the device requests looking for a matching linux driver to handle them. */
static int linux_probe(struct root_device *rootdev)
{
	struct linux_device_request *request;
	struct linux_driver *driver;
	struct linux_device *device = NULL;
	int rc;

	/* Apply global settings */
	linux_apply_settings(&linux_global_settings, NULL);

	list_for_each_entry(request, &linux_device_requests, list) {
		if (! device)
			device = zalloc(sizeof(*device));

		if (! device)
			return -ENOMEM;

		rc = 1;

		for_each_table_entry(driver, LINUX_DRIVERS) {
			if ((rc = strcmp(driver->name, request->driver)) == 0)
				break;
		}

		if (rc != 0) {
			printf("Linux driver '%s' not found\n", request->driver);
			continue;
		}

		if (! driver->can_probe) {
			printf("Driver '%s' cannot handle any more devices\n", driver->name);
			continue;
		}

		/* We found a matching driver so add the device to the hierarchy */
		list_add(&device->dev.siblings, &rootdev->dev.children);
		device->dev.parent = &rootdev->dev;
		INIT_LIST_HEAD(&device->dev.children);

		if (driver->probe(device, request) == 0) {
			device->driver = driver;
			device->dev.driver_name = driver->name;
			/* Driver handled the device so release ownership */
			device = NULL;
		} else {
			/* Driver failed to handle the device so remove it from the hierarchy
			 * and reuse the object */
			list_del(&device->dev.siblings);
		}
	};

	free(device);

	return 0;
}

/** Remove all the linux devices registered in probe() */
static void linux_remove(struct root_device *rootdev)
{
	struct linux_device *device;
	struct linux_device *tmp;

	list_for_each_entry_safe(device, tmp, &rootdev->dev.children, dev.siblings) {
		list_del(&device->dev.siblings);
		device->driver->remove(device);
		free(device);
	}
}

/** Linux root driver */
static struct root_driver linux_root_driver = {
	.probe = linux_probe,
	.remove = linux_remove,
};

/** Linux root device */
struct root_device linux_root_device __root_device = {
	.dev = { .name = "linux" },
	.driver = &linux_root_driver,
};

struct linux_setting *linux_find_setting(char *name, struct list_head *settings)
{
	struct linux_setting *setting;
	struct linux_setting *result = NULL;

	/* Find the last occurrence of a setting with the specified name */
	list_for_each_entry(setting, settings, list) {
		if (strcmp(setting->name, name) == 0) {
			result = setting;
		}
	}

	return result;
}

/**
 * Apply Linux command-line settings
 *
 * @v list		List of command-line settings
 * @v settings		Settings block
 */
void linux_apply_settings ( struct list_head *list,
			    struct settings *settings ) {
	struct linux_setting *lsetting;
	struct settings *ignore;
	struct setting setting;
	int rc;

	list_for_each_entry ( lsetting, list, list ) {

		/* Skip already applied settings */
		if ( lsetting->applied )
			continue;

		/* Parse setting name */
		if ( ( rc = parse_setting_name ( lsetting->name,
						 find_child_settings, &ignore,
						 &setting ) ) != 0 ) {
			DBGC ( settings, "Linux cannot parse %s: %s\n",
			       lsetting->name, strerror ( rc ) );
			continue;
		}

		/* Apply default type if not specified */
		if ( ! setting.type )
			setting.type = &setting_type_string;

		/* Store setting */
		if ( ( rc = storef_setting ( settings, &setting,
					     lsetting->value ) ) != 0 ) {
			DBGC ( settings, "Linux cannot set %s=\"%s\": %s\n",
			       lsetting->name, lsetting->value,
			       strerror ( rc ) );
			continue;
		}

		/* Mark setting as applied */
		lsetting->applied = 1;
	}
}
