svn commit: r272737 - in head/sys: dev/mrsas modules/mrsas modules/mrsas/mrsas_linux

Kashyap D Desai kadesai at FreeBSD.org
Wed Oct 8 09:19:38 UTC 2014


Author: kadesai
Date: Wed Oct  8 09:19:35 2014
New Revision: 272737
URL: https://svnweb.freebsd.org/changeset/base/272737

Log:
  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

Added:
  head/sys/dev/mrsas/mrsas_linux.c   (contents, props changed)
  head/sys/modules/mrsas/mrsas_linux/
  head/sys/modules/mrsas/mrsas_linux/Makefile   (contents, props changed)
Modified:
  head/sys/dev/mrsas/mrsas.c
  head/sys/dev/mrsas/mrsas.h
  head/sys/dev/mrsas/mrsas_ioctl.c
  head/sys/dev/mrsas/mrsas_ioctl.h
  head/sys/modules/mrsas/Makefile

Modified: head/sys/dev/mrsas/mrsas.c
==============================================================================
--- head/sys/dev/mrsas/mrsas.c	Wed Oct  8 08:51:05 2014	(r272736)
+++ head/sys/dev/mrsas/mrsas.c	Wed Oct  8 09:19:35 2014	(r272737)
@@ -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 mrsa
 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 *s
 	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
     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
 
 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);

Modified: head/sys/dev/mrsas/mrsas.h
==============================================================================
--- head/sys/dev/mrsas/mrsas.h	Wed Oct  8 08:51:05 2014	(r272736)
+++ head/sys/dev/mrsas/mrsas.h	Wed Oct  8 09:19:35 2014	(r272737)
@@ -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

Modified: head/sys/dev/mrsas/mrsas_ioctl.c
==============================================================================
--- head/sys/dev/mrsas/mrsas_ioctl.c	Wed Oct  8 08:51:05 2014	(r272736)
+++ head/sys/dev/mrsas/mrsas_ioctl.c	Wed Oct  8 09:19:35 2014	(r272737)
@@ -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
 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
  * 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 *
     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 *
         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 *
      * 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 *
                                 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 *
 
         /* 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 *
      * 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);
 

Modified: head/sys/dev/mrsas/mrsas_ioctl.h
==============================================================================
--- head/sys/dev/mrsas/mrsas_ioctl.h	Wed Oct  8 08:51:05 2014	(r272736)
+++ head/sys/dev/mrsas/mrsas_ioctl.h	Wed Oct  8 09:19:35 2014	(r272737)
@@ -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 */

Added: head/sys/dev/mrsas/mrsas_linux.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/dev/mrsas/mrsas_linux.c	Wed Oct  8 09:19:35 2014	(r272737)
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2014, LSI Corp.
+ * All rights reserved.
+ * Author: Kashyap Desai, Sibananda Sahu
+ * Support: freebsdraid at 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 at 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);

Modified: head/sys/modules/mrsas/Makefile
==============================================================================
--- head/sys/modules/mrsas/Makefile	Wed Oct  8 08:51:05 2014	(r272736)
+++ head/sys/modules/mrsas/Makefile	Wed Oct  8 09:19:35 2014	(r272737)
@@ -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*

Added: head/sys/modules/mrsas/mrsas_linux/Makefile
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/modules/mrsas/mrsas_linux/Makefile	Wed Oct  8 09:19:35 2014	(r272737)
@@ -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>


More information about the svn-src-all mailing list