#!/usr/bin/perl
#############################################################################
#
#		Copyright (c) 2004-2007, Broadcom Corporation.
#		All rights reserved.
#		Confidential Property of Broadcom Corporation.
#
#  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
#  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
#  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
#
# $brcm_Workfile: bapi_usercall.pm $
# $brcm_Revision: 5 $
# $brcm_Date: 1/5/07 11:52a $
#
# File Description:
#
# Revision History:
#
# $brcm_Log: /BSEAV/api/build/proxy/bapi_usercall.pm $
# 
# 5   1/5/07 11:52a erickson
# PR26790: for proxy-layer callback conversion, we must convert back on
# callback out params.
# 
# 4   3/15/06 4:51p vsilyaev
# PR20221: NetIF DMA interface
# 
# 3   9/12/05 12:35p mphillip
# PR16870: Fix kernel-mode macrovision support
# 
# 2   9/8/05 6:23p mphillip
# PR16870: Support for the macrovision data in bdisplay_settings
# 
# 1   2/7/05 6:56p dlwin
# Merge down for release 2005_REFSW_MERGETOMAIN:
# 
# Irvine_BSEAVSW_Devel/10   1/26/05 11:04a erickson
# PR13837: convert buffer_base to user address
# 
# Irvine_BSEAVSW_Devel/9   7/23/04 2:41p erickson
# PR11771: updated proxy layer for settop api changes
# 
# Irvine_BSEAVSW_Devel/8   7/9/04 1:38p erickson
# PR11771: rebuilt proxy layer for settop api dataflow redesign, and
# handle all callbacks with new perl module
#
# Irvine_BSEAVSW_Devel/7   6/24/04 10:24a erickson
# PR11135: added "don't modify" headers
#
# Irvine_BSEAVSW_Devel/6   6/18/04 12:33p erickson
# PR11135: added some timing debug code which can be uncommented if
# needed
#
# Irvine_BSEAVSW_Devel/5   6/17/04 9:37a erickson
# PR11135: recpump callback enabled
#
# Irvine_BSEAVSW_Devel/4   6/16/04 5:16p erickson
# PR11135: added callback support
#
# Irvine_BSEAVSW_Devel/3   6/2/04 2:45p erickson
# PR11204: changed/removed deprecated settop api functions
#
# Irvine_BSEAVSW_Devel/2   6/1/04 11:28a erickson
# PR11135: added comment
#
# Irvine_BSEAVSW_Devel/1   5/17/04 11:14a erickson
# PR11135: added initial linux proxy impl
#
#############################################################################
use strict;
use bapi_callbacks;

package bapi_usercall;

sub parse
{
	my ($filename, @funcs) = @_;
	my $func;
	open FILE, ">$filename";

	print FILE "/*********************************\n";
	print FILE "*\n";
	print FILE "* This file is autogenerated. Do not modify.\n";
	print FILE "*\n";
	print FILE "*********************************/\n";

	for $func (@funcs) {
		my $params = $func->{PARAMS};
		my $param;

		print FILE "$func->{PROTOTYPE}\n\{\n";
		print FILE "  int rc;\n";

# NOTE: The following code can measure time delays across the proxy.
# See below for more code.
#		print FILE "  b_time_t start, end; int diff;\n";
#		print FILE "  b_time_get(&start);\n";

		# If no params, no ioctl
		if ($func->{NOSTRUCT}) {
			print FILE "  rc = ioctl(g_ioctl_fd, BSETTOP_IOCTL_$func->{FUNCNAME}, NULL);\n";
		}
		else {
			print FILE "  ioctl_settopapi_struct_$func->{FUNCNAME} st;\n";

			for $param (@$params) {
				print FILE "  st.$param->{NAME} = $param->{NAME};\n";
			}

			# handle callback sets
			my $callback_text = bapi_callbacks::build_user_callback($func, 1);
			if ($callback_text) {
				printf FILE $callback_text;
			}

			print FILE "  rc = ioctl(g_ioctl_fd, BSETTOP_IOCTL_$func->{FUNCNAME}, (void*)&st);\n";
		}

		# TODO: add a table for failure return codes?
		if ($func->{RETTYPE} eq "bresult") {
			print FILE "  if (rc) return BSETTOP_ERROR(berr_external_error);\n";
		}
		elsif ($func->{RETTYPE} eq "void") {
			print FILE "  if (rc) {BSETTOP_ERROR(berr_external_error);}\n";
		}
		elsif ($func->{RETTYPE} eq "long" ||
			$func->{RETTYPE} eq "off_t") {
			print FILE "  if (rc) {BSETTOP_ERROR(berr_external_error);return -1;}\n";
		}
		else {
			# print "'" . $func->{RETTYPE} . "'\n";
			print FILE "  if (rc) {BSETTOP_ERROR(berr_external_error);return NULL;}\n";
		}

# NOTE: The following code can measure time delays across the proxy.
# See above for more code.
#		print FILE "  b_time_get(&end);\n";
#		print FILE "  diff = b_time_diff(&end, &start);\n";
#		print FILE "  if (diff > 10) BDBG_ERR((\"delay %d, line %d\", diff, __LINE__));\n";

		#
		# mmap any memory returned by the driver
		#
		my $maps = "";
		for $param (@$params) {
			if ($param->{ISREF} && ($param->{BASETYPE} =~ /\*/)) {
				$maps .= "  *st.$param->{NAME} = b_kernel2user((unsigned long)*st.$param->{NAME}, true);\n";
			}
		}
		if ($func->{FUNCNAME} eq "bsurface_get_memory") {
			$maps .= "  memory->buffer = b_kernel2user((unsigned long)memory->buffer, true);\n";
		}
		if ($func->{FUNCNAME} eq "bplaypump_get_status") {
			$maps .= "  status->buffer_base = b_kernel2user((unsigned long)status->buffer_base, true);\n";
		}
		
		# handle callback gets (reverse lookup)
		my $callback_text = bapi_callbacks::build_user_callback($func, 0);
		if ($callback_text) {
			printf FILE $callback_text;
		}
		

		if ($func->{RETTYPE} ne "void") {
			if ($maps) {
				print FILE "  if (!st.__retval) {\n";
				print FILE $maps;
				print FILE "  }\n";
			}
			print FILE "  return st.__retval;\n";
		}
		else {
			if ($maps) {
				print FILE $maps;
			}
		}
		print FILE "}\n\n";
	}
	close FILE;
}

1;
