diff --git a/sys/dev/mrsas/mrsas.c b/sys/dev/mrsas/mrsas.c index 279ab7b48f5..7e327cdab81 100644 --- a/sys/dev/mrsas/mrsas.c +++ b/sys/dev/mrsas/mrsas.c @@ -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); diff --git a/sys/dev/mrsas/mrsas.h b/sys/dev/mrsas/mrsas.h index a925047ab76..0798cc0c14c 100644 --- a/sys/dev/mrsas/mrsas.h +++ b/sys/dev/mrsas/mrsas.h @@ -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 diff --git a/sys/dev/mrsas/mrsas_ioctl.c b/sys/dev/mrsas/mrsas_ioctl.c index 6343aa59560..1e77fd87dec 100644 --- a/sys/dev/mrsas/mrsas_ioctl.c +++ b/sys/dev/mrsas/mrsas_ioctl.c @@ -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 @@ out: if (ioctl_data_tag[i] != NULL) bus_dma_tag_destroy(ioctl_data_tag[i]); } - /* Free command */ mrsas_release_mfi_cmd(cmd); diff --git a/sys/dev/mrsas/mrsas_ioctl.h b/sys/dev/mrsas/mrsas_ioctl.h index 36048427767..ae0e2e10d73 100644 --- a/sys/dev/mrsas/mrsas_ioctl.h +++ b/sys/dev/mrsas/mrsas_ioctl.h @@ -51,6 +51,15 @@ __FBSDID("$FreeBSD$"); #include #endif /* !_IOWR */ +#ifdef COMPAT_FREEBSD32 +/* Compilation error FIX */ +#if (__FreeBSD_version <= 900000) +#include +#endif +#include +#include +#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 */ diff --git a/sys/dev/mrsas/mrsas_linux.c b/sys/dev/mrsas/mrsas_linux.c new file mode 100644 index 00000000000..fd1d7093f46 --- /dev/null +++ b/sys/dev/mrsas/mrsas_linux.c @@ -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 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: + * Mail to: LSI Corporation, 1621 Barber Lane, Milpitas, CA 95035 + * ATTN: MegaRaid FreeBSD + * + */ + +#include + + +#include +#include + +#if (__FreeBSD_version > 900000) +#include +#endif + +#include +#include +#include +#include +#include +#include + +#if defined(__amd64__) /* Assume amd64 wants 32 bit Linux */ +#include +#include +#else +#include +#include +#endif +#include +#include + +#include +#include + +/* 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); diff --git a/sys/modules/mrsas/Makefile b/sys/modules/mrsas/Makefile index 7ff6c811f40..480f4ab3c1f 100644 --- a/sys/modules/mrsas/Makefile +++ b/sys/modules/mrsas/Makefile @@ -1,14 +1,24 @@ -# $FreeBSD$ +# Makefile for mrsas driver + -.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 -#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* diff --git a/sys/modules/mrsas/mrsas_linux/Makefile b/sys/modules/mrsas/mrsas_linux/Makefile new file mode 100644 index 00000000000..9b1039022a8 --- /dev/null +++ b/sys/modules/mrsas/mrsas_linux/Makefile @@ -0,0 +1,10 @@ +# Makefile for mrsas driver + + +.PATH: ${.CURDIR}/../../../dev/mrsas + +KMOD= mrsas_linux +SRCS= mrsas_linux.c +SRCS+= device_if.h bus_if.h pci_if.h + +.include