1158737Sambrisko/*-
2158737Sambrisko * Copyright (c) 2006 IronPort Systems
3158737Sambrisko * All rights reserved.
4158737Sambrisko *
5158737Sambrisko * Redistribution and use in source and binary forms, with or without
6158737Sambrisko * modification, are permitted provided that the following conditions
7158737Sambrisko * are met:
8158737Sambrisko * 1. Redistributions of source code must retain the above copyright
9158737Sambrisko *    notice, this list of conditions and the following disclaimer.
10158737Sambrisko * 2. Redistributions in binary form must reproduce the above copyright
11158737Sambrisko *    notice, this list of conditions and the following disclaimer in the
12158737Sambrisko *    documentation and/or other materials provided with the distribution.
13158737Sambrisko *
14158737Sambrisko * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15158737Sambrisko * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16158737Sambrisko * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17158737Sambrisko * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18158737Sambrisko * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19158737Sambrisko * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20158737Sambrisko * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21158737Sambrisko * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22158737Sambrisko * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23158737Sambrisko * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24158737Sambrisko * SUCH DAMAGE.
25158737Sambrisko */
26158737Sambrisko
27158737Sambrisko#include <sys/cdefs.h>
28158737Sambrisko__FBSDID("$FreeBSD$");
29158737Sambrisko
30158737Sambrisko#include <sys/param.h>
31158737Sambrisko#include <sys/systm.h>
32224778Srwatson#include <sys/capability.h>
33158737Sambrisko#include <sys/conf.h>
34158737Sambrisko#include <sys/kernel.h>
35158737Sambrisko#include <sys/module.h>
36158737Sambrisko#include <sys/file.h>
37158737Sambrisko#include <sys/proc.h>
38233711Sambrisko#include <machine/bus.h>
39158737Sambrisko
40158737Sambrisko#if defined(__amd64__) /* Assume amd64 wants 32 bit Linux */
41158737Sambrisko#include <machine/../linux32/linux.h>
42158737Sambrisko#include <machine/../linux32/linux32_proto.h>
43158737Sambrisko#else
44158737Sambrisko#include <machine/../linux/linux.h>
45158737Sambrisko#include <machine/../linux/linux_proto.h>
46158737Sambrisko#endif
47158737Sambrisko#include <compat/linux/linux_ioctl.h>
48158737Sambrisko#include <compat/linux/linux_util.h>
49158737Sambrisko
50164281Sambrisko#include <dev/mfi/mfireg.h>
51164281Sambrisko#include <dev/mfi/mfi_ioctl.h>
52164281Sambrisko
53158737Sambrisko/* There are multiple ioctl number ranges that need to be handled */
54158737Sambrisko#define MFI_LINUX_IOCTL_MIN  0x4d00
55158737Sambrisko#define MFI_LINUX_IOCTL_MAX  0x4d04
56158737Sambrisko
57158737Sambriskostatic linux_ioctl_function_t mfi_linux_ioctl;
58158737Sambriskostatic struct linux_ioctl_handler mfi_linux_handler = {mfi_linux_ioctl,
59158737Sambrisko						       MFI_LINUX_IOCTL_MIN,
60158737Sambrisko						       MFI_LINUX_IOCTL_MAX};
61158737Sambrisko
62158737SambriskoSYSINIT  (mfi_register,   SI_SUB_KLD, SI_ORDER_MIDDLE,
63158737Sambrisko	  linux_ioctl_register_handler, &mfi_linux_handler);
64158737SambriskoSYSUNINIT(mfi_unregister, SI_SUB_KLD, SI_ORDER_MIDDLE,
65158737Sambrisko	  linux_ioctl_unregister_handler, &mfi_linux_handler);
66158737Sambrisko
67158737Sambriskostatic struct linux_device_handler mfi_device_handler =
68158737Sambrisko	{ "mfi", "megaraid_sas", "mfi0", "megaraid_sas_ioctl_node", -1, 0, 1};
69158737Sambrisko
70158737SambriskoSYSINIT  (mfi_register2,   SI_SUB_KLD, SI_ORDER_MIDDLE,
71158737Sambrisko	  linux_device_register_handler, &mfi_device_handler);
72158737SambriskoSYSUNINIT(mfi_unregister2, SI_SUB_KLD, SI_ORDER_MIDDLE,
73158737Sambrisko	  linux_device_unregister_handler, &mfi_device_handler);
74158737Sambrisko
75158737Sambriskostatic int
76158737Sambriskomfi_linux_modevent(module_t mod, int cmd, void *data)
77158737Sambrisko{
78158737Sambrisko	return (0);
79158737Sambrisko}
80158737Sambrisko
81158737SambriskoDEV_MODULE(mfi_linux, mfi_linux_modevent, NULL);
82158737SambriskoMODULE_DEPEND(mfi, linux, 1, 1, 1);
83158737Sambrisko
84158737Sambriskostatic int
85192450Simpmfi_linux_ioctl(struct thread *p, struct linux_ioctl_args *args)
86158737Sambrisko{
87255219Spjd	cap_rights_t rights;
88158737Sambrisko	struct file *fp;
89158737Sambrisko	int error;
90164281Sambrisko	u_long cmd = args->cmd;
91158737Sambrisko
92164281Sambrisko	switch (cmd) {
93164281Sambrisko	case MFI_LINUX_CMD:
94164281Sambrisko		cmd = MFI_LINUX_CMD_2;
95164281Sambrisko		break;
96164281Sambrisko	case MFI_LINUX_SET_AEN:
97164281Sambrisko		cmd = MFI_LINUX_SET_AEN_2;
98164281Sambrisko		break;
99164281Sambrisko	}
100164281Sambrisko
101255219Spjd	error = fget(p, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp);
102255219Spjd	if (error != 0)
103158737Sambrisko		return (error);
104164281Sambrisko	error = fo_ioctl(fp, cmd, (caddr_t)args->arg, p->td_ucred, p);
105158737Sambrisko	fdrop(fp, p);
106158737Sambrisko	return (error);
107158737Sambrisko}
108