#pragma ident "$Revision$"

/*
 *    SAM-QFS_notice_begin
 *
 *      Solaris 2.x Sun Storage & Archiving Management File System
 *
 *		Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved.
 *
 *		U.S. Government Rights - Commercial software. Government users are
 *	subject to the Sun Microsystems, Inc. standard license agreement and applicable
 *	provisions of the FAR and its supplements.
 *
 *      	Use is subject to license terms. Sun, Sun Microsystems and the Sun logo
 *	are trademarks or registered trademarks of Sun Microsystems, Inc. in the U.S.
 *	and other countries.
 *
 *    SAM-QFS_notice_end
 */

/*
 *	LGPL NOTICE
 *
 *	This library is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU Lesser General Public
 *	License as published by the Free Software Foundation; either
 *	version 2.1 of the License, or (at your option) any later version.
 *
 *	This library 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
 *	Lesser General Public License for more details.
 *
 *	You should have received a copy of the GNU Lesser General Public
 *	License along with this library; if not, write to the Free Software
 *	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

/*
 * sam_syscall.c - Perform SAM-FS system call.
 */

/*
 * ANSI C headers.
 */
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <stropts.h>
#include <fcntl.h>

/*
 * POSIX headers.
 */
#include <sys/types.h>
#include <signal.h>

/*
 * Solaris includes.
 */
#include <syslog.h>

/*
 * SAM-FS headers.
 */
#include "sam/types.h"
#include "sam/lib.h"
#include "sam/syscall.h"
#include "sam/samioc.h"


/*
 * Perform SAM-FS system call using an ioctl().
 */
int
sam_syscall(int number,	/* System call number */
void *arg,		/* Argument structure */
int size)		/* Size of argument structure */
{

#ifdef linux
	int fd, cmd, ret = 0;
	struct sam_syscall_args scargs;

	fd = open(SAMSYS_CDEV_NAME, O_RDONLY);

	if (fd < 0) {
		return (-1);
	}

	scargs.cmd	= number;
	scargs.buf	= arg;
	scargs.size	= size;

	ret = ioctl(fd, SAMSYS_IOC_SAM_SYSCALL, (char *)&scargs);

	close(fd);
	return (ret);

#else /* linux */

	/*
	 * No system call number is used. Use an ioctl to communicate with the
	 * file system.
	 */

	static int syscall_fd = -1;
	struct sam_syscall_args	scargs;

	if (syscall_fd < 0) {

		/* Use only one file descriptor for all threads in this process. */

		syscall_fd = open(SAMDEV, O_RDONLY);

		if (syscall_fd < 0) {
			return (-1);
		}
	}

	scargs.cmd	= number;
	scargs.buf	= arg;
	scargs.size	= size;

	return (ioctl(syscall_fd, SAMDEV_CMD, (char *)&scargs));

#endif /* linux */

}
