/* _NVRM_COPYRIGHT_BEGIN_
 *
 * Copyright 2001-2002 by NVIDIA Corporation.  All rights reserved.  All
 * information contained herein is proprietary and confidential to NVIDIA
 * Corporation.  Any use, reproduction, or disclosure without the written
 * permission of NVIDIA Corporation is prohibited.
 *
 * _NVRM_COPYRIGHT_END_
 */

#include "nv-misc.h"
#include "os-interface.h"
#include "nv.h"
#include "nv-freebsd.h"

#ifdef NV_SUPPORT_LINUX_COMPAT /* (COMPAT_LINUX || COMPAT_LINUX32) */

#define LINUX_IOCTL_NVIDIA_MIN 0x4600
#define LINUX_IOCTL_NVIDIA_MAX 0x46ff

#if defined(NVCPU_X86)
#include "machine/../linux/linux.h"
#endif

#if defined(NVCPU_X86_64)
#include "machine/../linux32/linux.h"
#endif

int linux_ioctl_nvidia(d_thread_t *, struct linux_ioctl_args *);

int linux_ioctl_nvidia(
    d_thread_t *td,
    struct linux_ioctl_args *args
)
{
    /*
     * The range has already been checked, and the native NVIDIA ioctl()
     * implementation will throw out any commands it does not recognize.
     * There is no good reason why we should manually translate each and
     * every one of the possible NVIDIA ioctl commands.
     *
     * Since the Linux driver uses the _IO macros to encode the required
     * data, the native ioctl layer can determine the parameter size and
     * copy the user data in/out correctly.
     */

    return (ioctl(td, (struct ioctl_args *) args));
}

struct linux_ioctl_handler nvidia_handler = {
    linux_ioctl_nvidia,
    LINUX_IOCTL_NVIDIA_MIN,
    LINUX_IOCTL_NVIDIA_MAX
};
#endif /* NV_SUPPORT_LINUX_COMPAT */


void nvidia_linux_init(void)
{
#ifdef NV_SUPPORT_LINUX_COMPAT /* (COMPAT_LINUX || COMPAT_LINUX32) */
    linux_ioctl_register_handler(&nvidia_handler);
#endif
}

void nvidia_linux_exit(void)
{
#ifdef NV_SUPPORT_LINUX_COMPAT /* (COMPAT_LINUX || COMPAT_LINUX32) */
    linux_ioctl_unregister_handler(&nvidia_handler);
#endif
}

