/*
 * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
 *
 * 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 Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *
 * You can also choose to distribute this program under the terms of
 * the Unmodified Binary Distribution Licence (as given in the file
 * COPYING.UBDL), provided that you have satisfied its requirements.
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
FILE_SECBOOT ( PERMITTED );

#include <string.h>
#include <ipxe/interface.h>

/** @file
 *
 * Object interfaces
 *
 */

/*****************************************************************************
 *
 * The null interface
 *
 */

/**
 * Close null interface
 *
 * @v intf		Null interface
 * @v rc		Reason for close
 */
static void null_intf_close ( struct interface *intf __unused,
			      int rc __unused ) {

	/* Do nothing.  In particular, do not call intf_restart(),
	 * since that would result in an infinite loop.
	 */
}

/** Null interface operations */
static struct interface_operation null_intf_op[] = {
	INTF_OP ( intf_close, struct interface *, null_intf_close ),
};

/** Null interface descriptor */
struct interface_descriptor null_intf_desc =
	INTF_DESC_PURE ( null_intf_op );

/** The null interface */
struct interface null_intf = INTF_INIT ( null_intf_desc );

/*****************************************************************************
 *
 * Object interface plumbing
 *
 */

/**
 * Plug an object interface into a new destination object interface
 *
 * @v intf		Object interface
 * @v dest		New destination object interface
 *
 * The reference to the existing destination interface is dropped, a
 * reference to the new destination interface is obtained, and the
 * interface is updated to point to the new destination interface.
 */
void intf_plug ( struct interface *intf, struct interface *dest ) {

	if ( intf == &null_intf )
		return;

	DBGC ( INTF_COL ( intf ),
	       "INTF " INTF_INTF_FMT " replug to " INTF_FMT "\n",
	       INTF_INTF_DBG ( intf, intf->dest ), INTF_DBG ( dest ) );

	intf_get ( dest );
	intf_put ( intf->dest );
	intf->dest = dest;
}

/**
 * Plug two object interfaces together
 *
 * @v a			Object interface A
 * @v b			Object interface B
 *
 * Plugs interface A into interface B, and interface B into interface
 * A.  (The basic plug() function is unidirectional; this function is
 * merely a shorthand for two calls to plug(), hence the name.)
 */
void intf_plug_plug ( struct interface *a, struct interface *b ) {
	intf_plug ( a, b );
	intf_plug ( b, a );
}

/**
 * Unplug an object interface
 *
 * @v intf		Object interface
 */
void intf_unplug ( struct interface *intf ) {
	DBGC ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT " unplug\n",
	       INTF_INTF_DBG ( intf, intf->dest ) );
	intf_put ( intf->dest );
	intf->dest = &null_intf;
}

/**
 * Ignore all further operations on an object interface
 *
 * @v intf		Object interface
 */
void intf_nullify ( struct interface *intf ) {
	intf->desc = &null_intf_desc;
}

/**
 * Increment reference count on an object interface
 *
 * @v intf		Object interface
 * @ret intf		Object interface
 */
struct interface * intf_get ( struct interface *intf ) {
	ref_get ( intf->refcnt );
	return intf;
}

/**
 * Decrement reference count on an object interface
 *
 * @v intf		Object interface
 */
void intf_put ( struct interface *intf ) {
	ref_put ( intf->refcnt );
}

/**
 * Get pointer to object containing object interface
 *
 * @v intf		Object interface
 * @ret object		Containing object
 */
void * intf_object ( struct interface *intf ) {
	return ( ( ( void * ) intf ) - intf->desc->offset );
}

/**
 * Get pass-through interface
 *
 * @v intf		Object interface
 * @ret passthru	Pass-through interface, or NULL
 */
static struct interface * intf_get_passthru ( struct interface *intf ) {
	struct interface_descriptor *desc = intf->desc;

	if ( desc->passthru_offset ) {
		return ( ( ( void * ) intf ) + desc->passthru_offset );
	} else {
		return NULL;
	}
}

/**
 * Get object interface destination and operation method (without pass-through)
 *
 * @v intf		Object interface
 * @v type		Operation type
 * @ret dest		Destination interface
 * @ret func		Implementing method, or NULL
 */
void * intf_get_dest_op_no_passthru_untyped ( struct interface *intf,
					      void *type,
					      struct interface **dest ) {
	struct interface_descriptor *desc;
	struct interface_operation *op;
	unsigned int i;

	*dest = intf_get ( intf->dest );
	desc = (*dest)->desc;
	for ( i = desc->num_op, op = desc->op ; i ; i--, op++ ) {
		if ( op->type == type )
			return op->func;
	}

	return NULL;
}

/**
 * Get object interface destination and operation method
 *
 * @v intf		Object interface
 * @v type		Operation type
 * @ret dest		Destination interface
 * @ret func		Implementing method, or NULL
 */
void * intf_get_dest_op_untyped ( struct interface *intf, void *type,
				  struct interface **dest ) {
	void *func;

	while ( 1 ) {

		/* Search for an implementing method provided by the
		 * current destination interface.
		 */
		func = intf_get_dest_op_no_passthru_untyped( intf, type, dest );
		if ( func )
			return func;

		/* Pass through to the underlying interface, if applicable */
		if ( ! ( intf = intf_get_passthru ( *dest ) ) )
			return NULL;
		intf_put ( *dest );
	}
}

/*****************************************************************************
 *
 * Generic interface operations
 *
 */

/**
 * Close an object interface
 *
 * @v intf		Object interface
 * @v rc		Reason for close
 *
 * Note that this function merely informs the destination object that
 * the interface is about to be closed; it doesn't actually disconnect
 * the interface.  In most cases, you probably want to use
 * intf_shutdown() or intf_restart() instead.
 */
void intf_close ( struct interface *intf, int rc ) {
	struct interface *dest;
	intf_close_TYPE ( void * ) *op =
		intf_get_dest_op ( intf, intf_close, &dest );
	void *object = intf_object ( dest );

	DBGC ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT " close (%s)\n",
	       INTF_INTF_DBG ( intf, dest ), strerror ( rc ) );

	if ( op ) {
		op ( object, rc );
	} else {
		/* Default is to restart the interface */
		intf_restart ( dest, rc );
	}

	intf_put ( dest );
}

/**
 * Shut down an object interface
 *
 * @v intf		Object interface
 * @v rc		Reason for close
 *
 * Blocks further operations from being received via the interface,
 * executes a close operation on the destination interface, and
 * unplugs the interface.
 */
void intf_shutdown ( struct interface *intf, int rc ) {
	struct interface tmp;

	DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " shutting down (%s)\n",
	       INTF_DBG ( intf ), strerror ( rc ) );

	/* Block further operations */
	intf_nullify ( intf );

	/* Transfer destination to temporary interface */
	intf_temp_init ( &tmp, intf );
	tmp.dest = intf->dest;
	intf->dest = &null_intf;

	/* Notify destination of close via temporary interface */
	intf_close ( &tmp, rc );

	/* Unplug temporary interface */
	intf_unplug ( &tmp );
}

/**
 * Shut down multiple object interfaces
 *
 * @v intfs		Object interfaces
 * @v rc		Reason for close
 */
void intfs_vshutdown ( va_list intfs, int rc ) {
	struct interface *intf;
	va_list tmp;

	/* Nullify all interfaces to avoid potential loops */
	va_copy ( tmp, intfs );
	while ( ( intf = va_arg ( tmp, struct interface * ) ) )
		intf_nullify ( intf );
	va_end ( tmp );

	/* Shut down all interfaces */
	while ( ( intf = va_arg ( intfs, struct interface * ) ) )
		intf_shutdown ( intf, rc );
}

/**
 * Shut down multiple object interfaces
 *
 * @v rc		Reason for close
 * @v ...		Object interfaces
 */
void intfs_shutdown ( int rc, ... ) {
	va_list intfs;

	va_start ( intfs, rc );
	intfs_vshutdown ( intfs, rc );
	va_end ( intfs );
}

/**
 * Shut down and restart an object interface
 *
 * @v intf		Object interface
 * @v rc		Reason for close
 *
 * Shuts down the interface, then unblocks operations that were
 * blocked during shutdown.
 */
void intf_restart ( struct interface *intf, int rc ) {

	/* Shut down the interface */
	intf_shutdown ( intf, rc );

	DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " restarting\n",
	       INTF_DBG ( intf ) );

	/* Restore the interface descriptor.  Must be done after
	 * shutdown (rather than inhibiting intf_shutdown() from
	 * nullifying the descriptor) in order to avoid a potential
	 * infinite loop as the intf_close() operations on each side
	 * of the link call each other recursively.
	 */
	intf_reinit ( intf );
}

/**
 * Shut down and restart multiple object interfaces
 *
 * @v intfs		Object interfaces
 * @v rc		Reason for close
 */
void intfs_vrestart ( va_list intfs, int rc ) {
	struct interface *intf;
	va_list tmp;

	/* Shut down all interfaces */
	va_copy ( tmp, intfs );
	intfs_vshutdown ( tmp, rc );
	va_end ( tmp );

	/* Reinitialise all interfaces */
	while ( ( intf = va_arg ( intfs, struct interface * ) ) )
		intf_reinit ( intf );
}

/**
 * Shut down and restart multiple object interfaces
 *
 * @v rc		Reason for close
 * @v ...		Object interfaces
 */
void intfs_restart ( int rc, ... ) {
	va_list intfs;

	va_start ( intfs, rc );
	intfs_vrestart ( intfs, rc );
	va_end ( intfs );
}

/**
 * Insert a filter interface
 *
 * @v intf		Object interface
 * @v upper		Upper end of filter
 * @v lower		Lower end of filter
 */
void intf_insert ( struct interface *intf, struct interface *upper,
		   struct interface *lower ) {
	struct interface *dest = intf->dest;

	intf_get ( dest );
	intf_plug_plug ( intf, upper );
	intf_plug_plug ( lower, dest );
	intf_put ( dest );
}

/**
 * Poke an object interface
 *
 * @v intf		Object interface
 * @v type		Operation type
 *
 * This is a helper function to implement methods which take no
 * parameters and return nothing.
 */
void intf_poke ( struct interface *intf,
		 void ( type ) ( struct interface *intf ) ) {
	struct interface *dest;
	intf_poke_TYPE ( void * ) *op =
		intf_get_dest_op_untyped ( intf, type, &dest );
	void *object = intf_object ( dest );

	if ( op ) {
		op ( object );
	} else {
		/* Default is to do nothing */
	}

	intf_put ( dest );
}
