This is a feature provided to run 32-bit linux binaries on FreeBSD 64bit

machine, for which 32bit compatibilty code has been added.
As in linux there is only one device entry that is used to fire IOCTL commands,
a new device entry megaraid_sas_ioctl_node is added for solely this
purpose.

From one dev node i.e mrgaraid_sa_ioctl_node we have to find out the
controller instance in case of multicontroller, for which one management info
structure has been added.

Reviewed by:	ambrisko
MFC after:		2 weeks
Sponsored by:	AVAGO Technologies
This commit is contained in:
kadesai 2014-10-08 09:19:35 +00:00
parent 0dadf7ed01
commit 5fd3e08489
7 changed files with 300 additions and 114 deletions

View File

@ -65,6 +65,7 @@ static d_read_t mrsas_read;
static d_write_t mrsas_write;
static d_ioctl_t mrsas_ioctl;
static struct mrsas_mgmt_info mrsas_mgmt_info;
static struct mrsas_ident *mrsas_find_ident(device_t);
static void mrsas_shutdown_ctlr(struct mrsas_softc *sc, u_int32_t opcode);
static void mrsas_flush_cache(struct mrsas_softc *sc);
@ -137,7 +138,7 @@ extern void mrsas_free_frame(struct mrsas_softc *sc, struct mrsas_mfi_cmd *cmd);
extern int mrsas_alloc_mfi_cmds(struct mrsas_softc *sc);
extern void mrsas_release_mpt_cmd(struct mrsas_mpt_cmd *cmd);
extern struct mrsas_mpt_cmd *mrsas_get_mpt_cmd(struct mrsas_softc *sc);
extern int mrsas_passthru(struct mrsas_softc *sc, void *arg);
extern int mrsas_passthru(struct mrsas_softc *sc, void *arg, u_long ioctlCmd);
extern uint8_t MR_ValidateMapInfo(struct mrsas_softc *sc);
extern u_int16_t MR_GetLDTgtId(u_int32_t ld, MR_DRV_RAID_MAP_ALL *map);
extern MR_LD_RAID *MR_LdRaidGet(u_int32_t ld, MR_DRV_RAID_MAP_ALL *map);
@ -657,7 +658,7 @@ mrsas_register_aen(struct mrsas_softc *sc, u_int32_t seq_num,
dcmd->data_xfer_len = sizeof(struct mrsas_evt_detail);
dcmd->opcode = MR_DCMD_CTRL_EVENT_WAIT;
dcmd->mbox.w[0] = seq_num;
sc->last_seq_num = seq_num;
sc->last_seq_num = seq_num;
dcmd->mbox.w[1] = curr_aen.word;
dcmd->sgl.sge32[0].phys_addr = (u_int32_t) sc->evt_detail_phys_addr;
dcmd->sgl.sge32[0].length = sizeof(struct mrsas_evt_detail);
@ -775,6 +776,8 @@ static int mrsas_attach(device_t dev)
sc->mrsas_cdev = make_dev(&mrsas_cdevsw, device_get_unit(dev), UID_ROOT,
GID_OPERATOR, (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP), "mrsas%u",
device_get_unit(dev));
if (device_get_unit(dev) == 0)
make_dev_alias(sc->mrsas_cdev, "megaraid_sas_ioctl_node");
if (sc->mrsas_cdev)
sc->mrsas_cdev->si_drv1 = sc;
@ -816,6 +819,17 @@ static int mrsas_attach(device_t dev)
goto fail_start_aen;
}
/*
* Add this controller to mrsas_mgmt_info structure so that it
* can be exported to management applications
*/
if (device_get_unit(dev) == 0)
memset(&mrsas_mgmt_info, 0, sizeof(mrsas_mgmt_info));
mrsas_mgmt_info.count++;
mrsas_mgmt_info.sc_ptr[mrsas_mgmt_info.max_index] = sc;
mrsas_mgmt_info.max_index++;
return (0);
fail_start_aen:
@ -858,6 +872,19 @@ static int mrsas_detach(device_t dev)
sc = device_get_softc(dev);
sc->remove_in_progress = 1;
/*
* Take the instance off the instance array. Note that we will not
* decrement the max_index. We let this array be sparse array
*/
for (i = 0; i < mrsas_mgmt_info.max_index; i++) {
if (mrsas_mgmt_info.sc_ptr[i] == sc) {
mrsas_mgmt_info.count--;
mrsas_mgmt_info.sc_ptr[i] = NULL;
break;
}
}
if(sc->ocr_thread_active)
wakeup(&sc->ocr_chan);
while(sc->reset_in_progress){
@ -1101,8 +1128,19 @@ mrsas_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, d_thread_t *td)
struct mrsas_softc *sc;
int ret = 0, i = 0;
sc = (struct mrsas_softc *)(dev->si_drv1);
struct mrsas_iocpacket *user_ioc = (struct mrsas_iocpacket *)arg;
/* get the Host number & the softc from data sent by the Application */
sc = mrsas_mgmt_info.sc_ptr[user_ioc->host_no];
if ((mrsas_mgmt_info.max_index == user_ioc->host_no) || (sc == NULL)) {
printf ("Please check the controller number\n");
if (sc == NULL)
printf ("There is NO such Host no. %d\n", user_ioc->host_no);
return ENOENT;
}
if (sc->remove_in_progress) {
mrsas_dprint(sc, MRSAS_INFO,
"Driver remove or shutdown called.\n");
@ -1131,12 +1169,17 @@ mrsas_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, d_thread_t *td)
do_ioctl:
switch (cmd) {
case MRSAS_IOC_FIRMWARE_PASS_THROUGH:
ret = mrsas_passthru(sc, (void *)arg);
case MRSAS_IOC_FIRMWARE_PASS_THROUGH64:
#ifdef COMPAT_FREEBSD32
case MRSAS_IOC_FIRMWARE_PASS_THROUGH32:
#endif
ret = mrsas_passthru(sc, (void *)arg, cmd);
break;
case MRSAS_IOC_SCAN_BUS:
ret = mrsas_bus_scan(sc);
break;
default:
mrsas_dprint(sc, MRSAS_TRACE, "IOCTL command 0x%lx is not handled\n", cmd);
}
return (ret);

View File

@ -2419,6 +2419,14 @@ struct mrsas_evt_detail {
} __packed;
/* Controller management info added to support Linux Emulator */
#define MAX_MGMT_ADAPTERS 1024
struct mrsas_mgmt_info {
u_int16_t count;
struct mrsas_softc *sc_ptr[MAX_MGMT_ADAPTERS];
int max_index;
};
/*******************************************************************
* per-instance data

View File

@ -51,11 +51,9 @@ __FBSDID("$FreeBSD$");
* Function prototypes
*/
int mrsas_alloc_mfi_cmds(struct mrsas_softc *sc);
int mrsas_passthru(struct mrsas_softc *sc, void *arg);
int mrsas_passthru(struct mrsas_softc *sc, void *arg, u_long ioctlCmd);
void mrsas_free_ioc_cmd(struct mrsas_softc *sc);
void mrsas_free_frame(struct mrsas_softc *sc, struct mrsas_mfi_cmd *cmd);
void mrsas_dump_dcmd(struct mrsas_softc *sc, struct mrsas_dcmd_frame* dcmd);
void mrsas_dump_ioctl(struct mrsas_softc *sc, struct mrsas_iocpacket *user_ioc);
void * mrsas_alloc_frame(struct mrsas_softc *sc, struct mrsas_mfi_cmd *cmd);
static int mrsas_create_frame_pool(struct mrsas_softc *sc);
static void mrsas_alloc_cb(void *arg, bus_dma_segment_t *segs,
@ -66,79 +64,6 @@ extern void mrsas_release_mfi_cmd(struct mrsas_mfi_cmd *cmd);
extern int mrsas_issue_blocked_cmd(struct mrsas_softc *sc,
struct mrsas_mfi_cmd *cmd);
/**
* mrsas_dump_ioctl: Print debug output for DCMDs
* input: Adapter instance soft state
* DCMD frame structure
*
* This function is called from mrsas_passthru() to print out debug information
* in the handling and routing of DCMD commands.
*/
void mrsas_dump_dcmd( struct mrsas_softc *sc, struct mrsas_dcmd_frame* dcmd )
{
int i;
device_printf(sc->mrsas_dev, "dcmd->cmd: 0x%02hhx\n", dcmd->cmd);
device_printf(sc->mrsas_dev, "dcmd->cmd_status: 0x%02hhx\n", dcmd->cmd_status);
device_printf(sc->mrsas_dev, "dcmd->sge_count: 0x%02hhx\n", dcmd->sge_count);
device_printf(sc->mrsas_dev, "dcmd->context: 0x%08x\n", dcmd->context);
device_printf(sc->mrsas_dev, "dcmd->flags: 0x%04hx\n", dcmd->flags);
device_printf(sc->mrsas_dev, "dcmd->timeout: 0x%04hx\n", dcmd->timeout);
device_printf(sc->mrsas_dev, "dcmd->data_xfer_len: 0x%08x\n", dcmd->data_xfer_len);
device_printf(sc->mrsas_dev, "dcmd->opcode: 0x%08x\n", dcmd->opcode);
device_printf(sc->mrsas_dev, "dcmd->mbox.w[0]: 0x%08x\n", dcmd->mbox.w[0]);
device_printf(sc->mrsas_dev, "dcmd->mbox.w[1]: 0x%08x\n", dcmd->mbox.w[1]);
device_printf(sc->mrsas_dev, "dcmd->mbox.w[2]: 0x%08x\n", dcmd->mbox.w[2]);
for (i=0; i< MIN(MAX_IOCTL_SGE, dcmd->sge_count); i++) {
device_printf(sc->mrsas_dev, "sgl[%02d]\n", i);
device_printf(sc->mrsas_dev, " sge32[%02d].phys_addr: 0x%08x\n",
i, dcmd->sgl.sge32[i].phys_addr);
device_printf(sc->mrsas_dev, " sge32[%02d].length: 0x%08x\n",
i, dcmd->sgl.sge32[i].length);
device_printf(sc->mrsas_dev, " sge64[%02d].phys_addr: 0x%08llx\n",
i, (long long unsigned int) dcmd->sgl.sge64[i].phys_addr);
device_printf(sc->mrsas_dev, " sge64[%02d].length: 0x%08x\n",
i, dcmd->sgl.sge64[i].length);
}
}
/**
* mrsas_dump_ioctl: Print debug output for ioctl
* input: Adapter instance soft state
* iocpacket structure
*
* This function is called from mrsas_passthru() to print out debug information
* in the handling and routing of ioctl commands.
*/
void mrsas_dump_ioctl(struct mrsas_softc *sc, struct mrsas_iocpacket *user_ioc)
{
union mrsas_frame *in_cmd = (union mrsas_frame *) &(user_ioc->frame.raw);
struct mrsas_dcmd_frame* dcmd = (struct mrsas_dcmd_frame *) &(in_cmd->dcmd);
int i;
device_printf(sc->mrsas_dev,
"====== In %s() ======================================\n", __func__);
device_printf(sc->mrsas_dev, "host_no: 0x%04hx\n", user_ioc->host_no);
device_printf(sc->mrsas_dev, " __pad1: 0x%04hx\n", user_ioc->__pad1);
device_printf(sc->mrsas_dev, "sgl_off: 0x%08x\n", user_ioc->sgl_off);
device_printf(sc->mrsas_dev, "sge_count: 0x%08x\n", user_ioc->sge_count);
device_printf(sc->mrsas_dev, "sense_off: 0x%08x\n", user_ioc->sense_off);
device_printf(sc->mrsas_dev, "sense_len: 0x%08x\n", user_ioc->sense_len);
mrsas_dump_dcmd(sc, dcmd);
for (i=0; i< MIN(MAX_IOCTL_SGE, user_ioc->sge_count); i++) {
device_printf(sc->mrsas_dev, "sge[%02d]\n", i);
device_printf(sc->mrsas_dev,
" iov_base: %p\n", user_ioc->sgl[i].iov_base);
device_printf(sc->mrsas_dev, " iov_len: %p\n",
(void*)user_ioc->sgl[i].iov_len);
}
device_printf(sc->mrsas_dev,
"==================================================================\n");
}
/**
* mrsas_passthru: Handle pass-through commands
* input: Adapter instance soft state
@ -147,9 +72,12 @@ void mrsas_dump_ioctl(struct mrsas_softc *sc, struct mrsas_iocpacket *user_ioc)
* This function is called from mrsas_ioctl() to handle pass-through and
* ioctl commands to Firmware.
*/
int mrsas_passthru( struct mrsas_softc *sc, void *arg )
int mrsas_passthru( struct mrsas_softc *sc, void *arg, u_long ioctlCmd )
{
struct mrsas_iocpacket *user_ioc = (struct mrsas_iocpacket *)arg;
#ifdef COMPAT_FREEBSD32
struct mrsas_iocpacket32 *user_ioc32 = (struct mrsas_iocpacket32 *)arg;
#endif
union mrsas_frame *in_cmd = (union mrsas_frame *) &(user_ioc->frame.raw);
struct mrsas_mfi_cmd *cmd = NULL;
bus_dma_tag_t ioctl_data_tag[MAX_IOCTL_SGE];
@ -160,12 +88,11 @@ int mrsas_passthru( struct mrsas_softc *sc, void *arg )
bus_dmamap_t ioctl_sense_dmamap = 0;
void *ioctl_sense_mem = 0;
bus_addr_t ioctl_sense_phys_addr = 0;
int i, adapter, ioctl_data_size, ioctl_sense_size, ret=0;
int i, ioctl_data_size=0, ioctl_sense_size, ret=0;
struct mrsas_sge32 *kern_sge32;
unsigned long *sense_ptr;
/* For debug - uncomment the following line for debug output */
//mrsas_dump_ioctl(sc, user_ioc);
uint8_t *iov_base_ptrin=NULL;
size_t iov_len=0;
/*
* Check for NOP from MegaCli... MegaCli can issue a DCMD of 0. In this
@ -177,13 +104,6 @@ int mrsas_passthru( struct mrsas_softc *sc, void *arg )
return (0);
}
/* Validate host_no */
adapter = user_ioc->host_no;
if (adapter != device_get_unit(sc->mrsas_dev)) {
device_printf(sc->mrsas_dev, "In %s() IOCTL not for me!\n", __func__);
return(ENOENT);
}
/* Validate SGL length */
if (user_ioc->sge_count > MAX_IOCTL_SGE) {
device_printf(sc->mrsas_dev, "In %s() SGL is too long (%d > 8).\n",
@ -225,9 +145,17 @@ int mrsas_passthru( struct mrsas_softc *sc, void *arg )
* For each user buffer, create a mirror buffer and copy in
*/
for (i=0; i < user_ioc->sge_count; i++) {
if (!user_ioc->sgl[i].iov_len)
continue;
ioctl_data_size = user_ioc->sgl[i].iov_len;
if (ioctlCmd == MRSAS_IOC_FIRMWARE_PASS_THROUGH64) {
if (!user_ioc->sgl[i].iov_len)
continue;
ioctl_data_size = user_ioc->sgl[i].iov_len;
#ifdef COMPAT_FREEBSD32
} else {
if (!user_ioc32->sgl[i].iov_len)
continue;
ioctl_data_size = user_ioc32->sgl[i].iov_len;
#endif
}
if (bus_dma_tag_create( sc->mrsas_parent_tag, // parent
1, 0, // algnmnt, boundary
BUS_SPACE_MAXADDR_32BIT,// lowaddr
@ -239,8 +167,8 @@ int mrsas_passthru( struct mrsas_softc *sc, void *arg )
BUS_DMA_ALLOCNOW, // flags
NULL, NULL, // lockfunc, lockarg
&ioctl_data_tag[i])) {
device_printf(sc->mrsas_dev, "Cannot allocate ioctl data tag\n");
return (ENOMEM);
device_printf(sc->mrsas_dev, "Cannot allocate ioctl data tag\n");
return (ENOMEM);
}
if (bus_dmamem_alloc(ioctl_data_tag[i], (void **)&ioctl_data_mem[i],
(BUS_DMA_NOWAIT | BUS_DMA_ZERO), &ioctl_data_dmamap[i])) {
@ -256,18 +184,31 @@ int mrsas_passthru( struct mrsas_softc *sc, void *arg )
/* Save the physical address and length */
kern_sge32[i].phys_addr = (u_int32_t)ioctl_data_phys_addr[i];
kern_sge32[i].length = user_ioc->sgl[i].iov_len;
if (ioctlCmd == MRSAS_IOC_FIRMWARE_PASS_THROUGH64) {
kern_sge32[i].length = user_ioc->sgl[i].iov_len;
iov_base_ptrin = user_ioc->sgl[i].iov_base;
iov_len = user_ioc->sgl[i].iov_len;
#ifdef COMPAT_FREEBSD32
} else {
kern_sge32[i].length = user_ioc32->sgl[i].iov_len;
iov_base_ptrin = PTRIN(user_ioc32->sgl[i].iov_base);
iov_len = user_ioc32->sgl[i].iov_len;
#endif
}
/* Copy in data from user space */
ret = copyin(user_ioc->sgl[i].iov_base, ioctl_data_mem[i],
user_ioc->sgl[i].iov_len);
ret = copyin(iov_base_ptrin, ioctl_data_mem[i], iov_len);
if (ret) {
device_printf(sc->mrsas_dev, "IOCTL copyin failed!\n");
goto out;
device_printf(sc->mrsas_dev, "IOCTL copyin failed!\n");
goto out;
}
}
ioctl_sense_size = user_ioc->sense_len;
if (user_ioc->sense_len) {
if (bus_dma_tag_create( sc->mrsas_parent_tag, // parent
1, 0, // algnmnt, boundary
@ -311,8 +252,17 @@ int mrsas_passthru( struct mrsas_softc *sc, void *arg )
* copy out the kernel buffers to user buffers
*/
for (i = 0; i < user_ioc->sge_count; i++) {
ret = copyout(ioctl_data_mem[i], user_ioc->sgl[i].iov_base,
user_ioc->sgl[i].iov_len);
if (ioctlCmd == MRSAS_IOC_FIRMWARE_PASS_THROUGH64) {
iov_base_ptrin = user_ioc->sgl[i].iov_base;
iov_len = user_ioc->sgl[i].iov_len;
#ifdef COMPAT_FREEBSD32
} else {
iov_base_ptrin = PTRIN(user_ioc32->sgl[i].iov_base);
iov_len = user_ioc32->sgl[i].iov_len;
#endif
}
ret = copyout(ioctl_data_mem[i], iov_base_ptrin, iov_len);
if (ret) {
device_printf(sc->mrsas_dev, "IOCTL copyout failed!\n");
goto out;
@ -368,7 +318,6 @@ int mrsas_passthru( struct mrsas_softc *sc, void *arg )
if (ioctl_data_tag[i] != NULL)
bus_dma_tag_destroy(ioctl_data_tag[i]);
}
/* Free command */
mrsas_release_mfi_cmd(cmd);

View File

@ -51,6 +51,15 @@ __FBSDID("$FreeBSD$");
#include <sys/ioccom.h>
#endif /* !_IOWR */
#ifdef COMPAT_FREEBSD32
/* Compilation error FIX */
#if (__FreeBSD_version <= 900000)
#include <sys/socket.h>
#endif
#include <sys/mount.h>
#include <compat/freebsd32/freebsd32.h>
#endif
/*
* We need to use the same values as the mfi driver until MegaCli adds
* support for this (mrsas) driver:
@ -61,10 +70,15 @@ __FBSDID("$FreeBSD$");
* These three values are encoded into a somewhat unique, 32-bit value.
*/
#define MRSAS_IOC_FIRMWARE_PASS_THROUGH _IOWR('M', 1, struct mrsas_iocpacket)
#define MRSAS_IOC_FIRMWARE_PASS_THROUGH64 _IOWR('M', 1, struct mrsas_iocpacket)
#ifdef COMPAT_FREEBSD32
#define MRSAS_IOC_FIRMWARE_PASS_THROUGH32 _IOWR('M', 1, struct mrsas_iocpacket32)
#endif
#define MRSAS_IOC_SCAN_BUS _IO('M', 10)
#define MRSAS_LINUX_CMD32 0xc1144d01
#define MAX_IOCTL_SGE 16
#define MFI_FRAME_DIR_READ 0x0010
#define MFI_CMD_LD_SCSI_IO 0x03
@ -94,4 +108,22 @@ struct mrsas_iocpacket {
};
#pragma pack()
#ifdef COMPAT_FREEBSD32
#pragma pack(1)
struct mrsas_iocpacket32 {
u_int16_t host_no;
u_int16_t __pad1;
u_int32_t sgl_off;
u_int32_t sge_count;
u_int32_t sense_off;
u_int32_t sense_len;
union {
u_int8_t raw[MEGAMFI_RAW_FRAME_SIZE];
struct mrsas_header hdr;
} frame;
struct iovec32 sgl[MAX_IOCTL_SGE];
};
#pragma pack()
#endif /* COMPAT_FREEBSD32 */
#endif /* MRSAS_IOCTL_H */

134
sys/dev/mrsas/mrsas_linux.c Normal file
View File

@ -0,0 +1,134 @@
/*
* Copyright (c) 2014, LSI Corp.
* All rights reserved.
* Author: Kashyap Desai, Sibananda Sahu
* Support: freebsdraid@lsi.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name of the <ORGANIZATION> nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation
* are those of the authors and should not be interpreted as representing
* official policies,either expressed or implied, of the FreeBSD Project.
*
* Send feedback to: <megaraidfbsd@lsi.com>
* Mail to: LSI Corporation, 1621 Barber Lane, Milpitas, CA 95035
* ATTN: MegaRaid FreeBSD
*
*/
#include <sys/cdefs.h>
<!-- $FreeBSD$ -->
#include <sys/param.h>
#include <sys/systm.h>
#if (__FreeBSD_version > 900000)
#include <sys/capability.h>
#endif
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/file.h>
#include <sys/proc.h>
#include <machine/bus.h>
#if defined(__amd64__) /* Assume amd64 wants 32 bit Linux */
#include <machine/../linux32/linux.h>
#include <machine/../linux32/linux32_proto.h>
#else
#include <machine/../linux/linux.h>
#include <machine/../linux/linux_proto.h>
#endif
#include <compat/linux/linux_ioctl.h>
#include <compat/linux/linux_util.h>
#include <dev/mrsas/mrsas.h>
#include <dev/mrsas/mrsas_ioctl.h>
/* There are multiple ioctl number ranges that need to be handled */
#define MRSAS_LINUX_IOCTL_MIN 0x4d00
#define MRSAS_LINUX_IOCTL_MAX 0x4d01
static linux_ioctl_function_t mrsas_linux_ioctl;
static struct linux_ioctl_handler mrsas_linux_handler = {mrsas_linux_ioctl,
MRSAS_LINUX_IOCTL_MIN,
MRSAS_LINUX_IOCTL_MAX};
SYSINIT (mrsas_register, SI_SUB_KLD, SI_ORDER_MIDDLE,
linux_ioctl_register_handler, &mrsas_linux_handler);
SYSUNINIT(mrsas_unregister, SI_SUB_KLD, SI_ORDER_MIDDLE,
linux_ioctl_unregister_handler, &mrsas_linux_handler);
static struct linux_device_handler mrsas_device_handler =
{ "mrsas", "megaraid_sas", "mrsas0", "megaraid_sas_ioctl_node", -1, 0, 1};
SYSINIT (mrsas_register2, SI_SUB_KLD, SI_ORDER_MIDDLE,
linux_device_register_handler, &mrsas_device_handler);
SYSUNINIT(mrsas_unregister2, SI_SUB_KLD, SI_ORDER_MIDDLE,
linux_device_unregister_handler, &mrsas_device_handler);
static int
mrsas_linux_modevent(module_t mod __unused, int cmd __unused, void *data __unused)
{
return (0);
}
static int
mrsas_linux_ioctl(struct thread *p, struct linux_ioctl_args *args)
{
#if (__FreeBSD_version >= 1000000)
cap_rights_t rights;
#endif
struct file *fp;
int error;
u_long cmd = args->cmd;
if (cmd != MRSAS_LINUX_CMD32){
error = ENOTSUP;
goto END;
}
#if (__FreeBSD_version >= 1000000)
error = fget(p, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp);
#elif (__FreeBSD_version <= 900000)
error = fget(p, args->fd, &fp);
#else /* For FreeBSD version greater than 9.0.0 but less than 10.0.0 */
error = fget(p, args->fd, CAP_IOCTL, &fp);
#endif
if (error != 0)
goto END;
error = fo_ioctl(fp, cmd, (caddr_t)args->arg, p->td_ucred, p);
fdrop(fp, p);
END:
return (error);
}
DEV_MODULE(mrsas_linux, mrsas_linux_modevent, NULL);
MODULE_DEPEND(mrsas, linux, 1, 1, 1);

View File

@ -1,14 +1,24 @@
# $FreeBSD$
# Makefile for mrsas driver
<!-- $FreeBSD$ -->
.PATH: ${.CURDIR}/../../dev/mrsas
KMOD=mrsas
.PATH: ${.CURDIR}/../../dev/${KMOD}
KMOD= mrsas
SRCS= mrsas.c mrsas_cam.c mrsas_ioctl.c mrsas_fp.c
SRCS+= device_if.h bus_if.h pci_if.h opt_cam.h opt_scsi.h
.if ${MACHINE_ARCH} == "i386" || ${MACHINE_ARCH} == "amd64"
SUBDIR+= mrsas_linux
.endif
SRCS=mrsas.c mrsas_cam.c mrsas_ioctl.c mrsas_fp.c
SRCS+= device_if.h bus_if.h pci_if.h opt_cam.h opt_scsi.h
#CFLAGS+= -MRSAS_DEBUG
.include <bsd.kmod.mk>
#CFLAGS+= -fgnu89-inline
CFLAGS+= -fgnu89-inline
TARGET_ARCH = ${MACHINE_ARCH}
.if ${TARGET_ARCH} == "amd64"
CFLAGS+= -DCOMPAT_FREEBSD32 -D_STANDALONE
.endif
clean_cscope:
rm -f cscope*

View File

@ -0,0 +1,10 @@
# Makefile for mrsas driver
<!-- $FreeBSD$ -->
.PATH: ${.CURDIR}/../../../dev/mrsas
KMOD= mrsas_linux
SRCS= mrsas_linux.c
SRCS+= device_if.h bus_if.h pci_if.h
.include <bsd.kmod.mk>