Author: kadesai
Date: Fri May 13 12:05:02 2016
New Revision: 299667
URL: https://svnweb.freebsd.org/changeset/base/299667

Log:
  Similar to RAID map for Logical Drives, now JBOD map has been introduced for
  JBODs. Driver has to sync the JBOD map with firmware and use sequence number
  as a reference for JBOD FastPath I/O's.
  
  Submitted by:   Sumit Saxena <sumit.sax...@broadcom.com>
  Reviewed by:    Kashyap Desai <kashyap.de...@broadcom.com>
  MFC after:  3 days
  Sponsored by:   AVAGO Technologies

Modified:
  head/sys/dev/mrsas/mrsas.c
  head/sys/dev/mrsas/mrsas.h
  head/sys/dev/mrsas/mrsas_cam.c

Modified: head/sys/dev/mrsas/mrsas.c
==============================================================================
--- head/sys/dev/mrsas/mrsas.c  Fri May 13 12:00:46 2016        (r299666)
+++ head/sys/dev/mrsas/mrsas.c  Fri May 13 12:05:02 2016        (r299667)
@@ -80,6 +80,8 @@ static int mrsas_setup_irq(struct mrsas_
 static int mrsas_alloc_mem(struct mrsas_softc *sc);
 static int mrsas_init_fw(struct mrsas_softc *sc);
 static int mrsas_setup_raidmap(struct mrsas_softc *sc);
+static void megasas_setup_jbod_map(struct mrsas_softc *sc);
+static int megasas_sync_pd_seq_num(struct mrsas_softc *sc, boolean_t pend);
 static int mrsas_complete_cmd(struct mrsas_softc *sc, u_int32_t MSIxIndex);
 static int mrsas_clear_intr(struct mrsas_softc *sc);
 static int mrsas_get_ctrl_info(struct mrsas_softc *sc);
@@ -1076,7 +1078,14 @@ mrsas_free_mem(struct mrsas_softc *sc)
                if (sc->ld_drv_map[i] != NULL)
                        free(sc->ld_drv_map[i], M_MRSAS);
        }
-
+       for (i = 0; i < 2; i++) {
+               if (sc->jbodmap_phys_addr[i])
+                       bus_dmamap_unload(sc->jbodmap_tag[i], 
sc->jbodmap_dmamap[i]);
+               if (sc->jbodmap_mem[i] != NULL)
+                       bus_dmamem_free(sc->jbodmap_tag[i], sc->jbodmap_mem[i], 
sc->jbodmap_dmamap[i]);
+               if (sc->jbodmap_tag[i] != NULL)
+                       bus_dma_tag_destroy(sc->jbodmap_tag[i]);
+       }
        /*
         * Free version buffer memory
         */
@@ -1997,6 +2006,78 @@ ABORT:
        return (1);
 }
 
+/**
+ * megasas_setup_jbod_map -    setup jbod map for FP seq_number.
+ * @sc:                                Adapter soft state
+ *
+ * Return 0 on success.
+ */
+void
+megasas_setup_jbod_map(struct mrsas_softc *sc)
+{
+       int i;
+       uint32_t pd_seq_map_sz;
+
+       pd_seq_map_sz = sizeof(struct MR_PD_CFG_SEQ_NUM_SYNC) +
+           (sizeof(struct MR_PD_CFG_SEQ) * (MAX_PHYSICAL_DEVICES - 1));
+
+       if (!sc->ctrl_info->adapterOperations3.useSeqNumJbodFP) {
+               sc->use_seqnum_jbod_fp = 0;
+               return;
+       }
+       if (sc->jbodmap_mem[0])
+               goto skip_alloc;
+
+       for (i = 0; i < 2; i++) {
+               if (bus_dma_tag_create(sc->mrsas_parent_tag,
+                   4, 0,
+                   BUS_SPACE_MAXADDR_32BIT,
+                   BUS_SPACE_MAXADDR,
+                   NULL, NULL,
+                   pd_seq_map_sz,
+                   1,
+                   pd_seq_map_sz,
+                   BUS_DMA_ALLOCNOW,
+                   NULL, NULL,
+                   &sc->jbodmap_tag[i])) {
+                       device_printf(sc->mrsas_dev,
+                           "Cannot allocate jbod map tag.\n");
+                       return;
+               }
+               if (bus_dmamem_alloc(sc->jbodmap_tag[i],
+                   (void **)&sc->jbodmap_mem[i],
+                   BUS_DMA_NOWAIT, &sc->jbodmap_dmamap[i])) {
+                       device_printf(sc->mrsas_dev,
+                           "Cannot allocate jbod map memory.\n");
+                       return;
+               }
+               bzero(sc->jbodmap_mem[i], pd_seq_map_sz);
+
+               if (bus_dmamap_load(sc->jbodmap_tag[i], sc->jbodmap_dmamap[i],
+                   sc->jbodmap_mem[i], pd_seq_map_sz,
+                   mrsas_addr_cb, &sc->jbodmap_phys_addr[i],
+                   BUS_DMA_NOWAIT)) {
+                       device_printf(sc->mrsas_dev, "Cannot load jbod map 
memory.\n");
+                       return;
+               }
+               if (!sc->jbodmap_mem[i]) {
+                       device_printf(sc->mrsas_dev,
+                           "Cannot allocate memory for jbod map.\n");
+                       sc->use_seqnum_jbod_fp = 0;
+                       return;
+               }
+       }
+
+skip_alloc:
+       if (!megasas_sync_pd_seq_num(sc, false) &&
+           !megasas_sync_pd_seq_num(sc, true))
+               sc->use_seqnum_jbod_fp = 1;
+       else
+               sc->use_seqnum_jbod_fp = 0;
+
+       device_printf(sc->mrsas_dev, "Jbod map is supported\n");
+}
+
 /*
  * mrsas_init_fw:      Initialize Firmware
  * input:                      Adapter soft state
@@ -2096,18 +2177,28 @@ mrsas_init_fw(struct mrsas_softc *sc)
        if (sc->secure_jbod_support)
                device_printf(sc->mrsas_dev, "FW supports SED \n");
 
+       if (sc->use_seqnum_jbod_fp)
+               device_printf(sc->mrsas_dev, "FW supports JBOD Map \n");
+
        if (mrsas_setup_raidmap(sc) != SUCCESS) {
-               device_printf(sc->mrsas_dev, "Set up RAID map failed.\n");
-               return (1);
+               device_printf(sc->mrsas_dev, "Error: RAID map setup FAILED !!! "
+                   "There seems to be some problem in the controller\n"
+                   "Please contact to the SUPPORT TEAM if the problem 
persists\n");
        }
+       megasas_setup_jbod_map(sc);
+
        /* For pass-thru, get PD/LD list and controller info */
        memset(sc->pd_list, 0,
            MRSAS_MAX_PD * sizeof(struct mrsas_pd_list));
-       mrsas_get_pd_list(sc);
-
+       if (mrsas_get_pd_list(sc) != SUCCESS) {
+               device_printf(sc->mrsas_dev, "Get PD list failed.\n");
+               return (1);
+       }
        memset(sc->ld_ids, 0xff, MRSAS_MAX_LD_IDS);
-       mrsas_get_ld_list(sc);
-
+       if (mrsas_get_ld_list(sc) != SUCCESS) {
+               device_printf(sc->mrsas_dev, "Get LD lsit failed.\n");
+               return (1);
+       }
        /*
         * Compute the max allowed sectors per IO: The controller info has
         * two limits on max sectors. Driver should use the minimum of these
@@ -2855,6 +2946,8 @@ mrsas_reset_ctrl(struct mrsas_softc *sc,
                        if (!mrsas_get_map_info(sc))
                                mrsas_sync_map_info(sc);
 
+                       megasas_setup_jbod_map(sc);
+
                        memset(sc->pd_list, 0,
                            MRSAS_MAX_PD * sizeof(struct mrsas_pd_list));
                        if (mrsas_get_pd_list(sc) != SUCCESS) {
@@ -3086,6 +3179,9 @@ mrsas_get_ctrl_info(struct mrsas_softc *
        do_ocr = 0;
        mrsas_update_ext_vd_details(sc);
 
+       sc->use_seqnum_jbod_fp =
+           sc->ctrl_info->adapterOperations3.useSeqNumJbodFP;
+
 dcmd_timeout:
        mrsas_free_ctlr_info_cmd(sc);
 
@@ -3480,6 +3576,28 @@ mrsas_complete_mptmfi_passthru(struct mr
                    cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_GET) {
                        sc->mrsas_aen_triggered = 0;
                }
+               /* FW has an updated PD sequence */
+               if ((cmd->frame->dcmd.opcode ==
+                   MR_DCMD_SYSTEM_PD_MAP_GET_INFO) &&
+                   (cmd->frame->dcmd.mbox.b[0] == 1)) {
+
+                       mtx_lock(&sc->raidmap_lock);
+                       sc->jbod_seq_cmd = NULL;
+                       mrsas_release_mfi_cmd(cmd);
+
+                       if (cmd_status == MFI_STAT_OK) {
+                               sc->pd_seq_map_id++;
+                               /* Re-register a pd sync seq num cmd */
+                               if (megasas_sync_pd_seq_num(sc, true))
+                                       sc->use_seqnum_jbod_fp = 0;
+                       } else {
+                               sc->use_seqnum_jbod_fp = 0;
+                               device_printf(sc->mrsas_dev,
+                                   "Jbod map sync failed, status=%x\n", 
cmd_status);
+                       }
+                       mtx_unlock(&sc->raidmap_lock);
+                       break;
+               }
                /* See if got an event notification */
                if (cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_WAIT)
                        mrsas_complete_aen(sc, cmd);
@@ -3542,9 +3660,10 @@ mrsas_shutdown_ctlr(struct mrsas_softc *
        }
        if (sc->aen_cmd)
                mrsas_issue_blocked_abort_cmd(sc, sc->aen_cmd);
-
        if (sc->map_update_cmd)
                mrsas_issue_blocked_abort_cmd(sc, sc->map_update_cmd);
+       if (sc->jbod_seq_cmd)
+               mrsas_issue_blocked_abort_cmd(sc, sc->jbod_seq_cmd);
 
        dcmd = &cmd->frame->dcmd;
        memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
@@ -3606,6 +3725,85 @@ mrsas_flush_cache(struct mrsas_softc *sc
        return;
 }
 
+int
+megasas_sync_pd_seq_num(struct mrsas_softc *sc, boolean_t pend)
+{
+       int retcode = 0;
+       u_int8_t do_ocr = 1;
+       struct mrsas_mfi_cmd *cmd;
+       struct mrsas_dcmd_frame *dcmd;
+       uint32_t pd_seq_map_sz;
+       struct MR_PD_CFG_SEQ_NUM_SYNC *pd_sync;
+       bus_addr_t pd_seq_h;
+
+       pd_seq_map_sz = sizeof(struct MR_PD_CFG_SEQ_NUM_SYNC) +
+           (sizeof(struct MR_PD_CFG_SEQ) *
+           (MAX_PHYSICAL_DEVICES - 1));
+
+       cmd = mrsas_get_mfi_cmd(sc);
+       if (!cmd) {
+               device_printf(sc->mrsas_dev,
+                   "Cannot alloc for ld map info cmd.\n");
+               return 1;
+       }
+       dcmd = &cmd->frame->dcmd;
+
+       pd_sync = (void *)sc->jbodmap_mem[(sc->pd_seq_map_id & 1)];
+       pd_seq_h = sc->jbodmap_phys_addr[(sc->pd_seq_map_id & 1)];
+       if (!pd_sync) {
+               device_printf(sc->mrsas_dev,
+                   "Failed to alloc mem for jbod map info.\n");
+               mrsas_release_mfi_cmd(cmd);
+               return (ENOMEM);
+       }
+       memset(pd_sync, 0, pd_seq_map_sz);
+       memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
+       dcmd->cmd = MFI_CMD_DCMD;
+       dcmd->cmd_status = 0xFF;
+       dcmd->sge_count = 1;
+       dcmd->timeout = 0;
+       dcmd->pad_0 = 0;
+       dcmd->data_xfer_len = (pd_seq_map_sz);
+       dcmd->opcode = (MR_DCMD_SYSTEM_PD_MAP_GET_INFO);
+       dcmd->sgl.sge32[0].phys_addr = (pd_seq_h);
+       dcmd->sgl.sge32[0].length = (pd_seq_map_sz);
+
+       if (pend) {
+               dcmd->mbox.b[0] = MRSAS_DCMD_MBOX_PEND_FLAG;
+               dcmd->flags = (MFI_FRAME_DIR_WRITE);
+               sc->jbod_seq_cmd = cmd;
+               if (mrsas_issue_dcmd(sc, cmd)) {
+                       device_printf(sc->mrsas_dev,
+                           "Fail to send sync map info command.\n");
+                       return 1;
+               } else
+                       return 0;
+       } else
+               dcmd->flags = MFI_FRAME_DIR_READ;
+
+       retcode = mrsas_issue_polled(sc, cmd);
+       if (retcode == ETIMEDOUT)
+               goto dcmd_timeout;
+
+       if (pd_sync->count > MAX_PHYSICAL_DEVICES) {
+               device_printf(sc->mrsas_dev,
+                   "driver supports max %d JBOD, but FW reports %d\n",
+                   MAX_PHYSICAL_DEVICES, pd_sync->count);
+               retcode = -EINVAL;
+       }
+       if (!retcode)
+               sc->pd_seq_map_id++;
+       do_ocr = 0;
+
+dcmd_timeout:
+       if (do_ocr)
+               sc->do_timedout_reset = MFI_DCMD_TIMEOUT_OCR;
+       else
+               mrsas_release_mfi_cmd(cmd);
+
+       return (retcode);
+}
+
 /*
  * mrsas_get_map_info:        Load and validate RAID map input:
  * Adapter instance soft state

Modified: head/sys/dev/mrsas/mrsas.h
==============================================================================
--- head/sys/dev/mrsas/mrsas.h  Fri May 13 12:00:46 2016        (r299666)
+++ head/sys/dev/mrsas/mrsas.h  Fri May 13 12:05:02 2016        (r299667)
@@ -577,6 +577,7 @@ Mpi2IOCInitRequest_t, MPI2_POINTER pMpi2
 #define        MAX_PHYSICAL_DEVICES    256
 #define        MAX_RAIDMAP_PHYSICAL_DEVICES    (MAX_PHYSICAL_DEVICES)
 #define        MR_DCMD_LD_MAP_GET_INFO 0x0300e101
+#define        MR_DCMD_SYSTEM_PD_MAP_GET_INFO  0x0200e102
 
 
 #define        MRSAS_MAX_PD_CHANNELS           1
@@ -863,6 +864,22 @@ struct IO_REQUEST_INFO {
        u_int8_t pd_after_lb;
 };
 
+/*
+ * define MR_PD_CFG_SEQ structure for system PDs
+ */
+struct MR_PD_CFG_SEQ {
+       u_int16_t seqNum;
+       u_int16_t devHandle;
+       u_int8_t reserved[4];
+} __packed;
+
+struct MR_PD_CFG_SEQ_NUM_SYNC {
+       u_int32_t size;
+       u_int32_t count;
+       struct MR_PD_CFG_SEQ seq[1];
+} __packed;
+
+
 typedef struct _MR_LD_TARGET_SYNC {
        u_int8_t targetId;
        u_int8_t reserved;
@@ -1927,7 +1944,12 @@ struct mrsas_ctrl_info {
                u_int32_t supportCacheBypassModes:1;
                u_int32_t supportSecurityonJBOD:1;
                u_int32_t discardCacheDuringLDDelete:1;
-               u_int32_t reserved:12;
+               u_int32_t supportTTYLogCompression:1;
+               u_int32_t supportCPLDUpdate:1;
+               u_int32_t supportDiskCacheSettingForSysPDs:1;
+               u_int32_t supportExtendedSSCSize:1;
+               u_int32_t useSeqNumJbodFP:1;
+               u_int32_t reserved:7;
        }       adapterOperations3;
 
        u_int8_t pad[0x800 - 0x7EC];    /* 0x7EC */
@@ -2697,7 +2719,9 @@ struct mrsas_softc {
        u_int8_t chain_offset_mfi_pthru;
        u_int32_t map_sz;
        u_int64_t map_id;
+       u_int64_t pd_seq_map_id;
        struct mrsas_mfi_cmd *map_update_cmd;
+       struct mrsas_mfi_cmd *jbod_seq_cmd;
        struct mrsas_mfi_cmd *aen_cmd;
        u_int8_t fast_path_io;
        void   *chan;
@@ -2708,6 +2732,12 @@ struct mrsas_softc {
        u_int8_t do_timedout_reset;
        u_int32_t reset_in_progress;
        u_int32_t reset_count;
+
+       bus_dma_tag_t jbodmap_tag[2];
+       bus_dmamap_t jbodmap_dmamap[2];
+       void   *jbodmap_mem[2];
+       bus_addr_t jbodmap_phys_addr[2];
+
        bus_dma_tag_t raidmap_tag[2];
        bus_dmamap_t raidmap_dmamap[2];
        void   *raidmap_mem[2];
@@ -2751,6 +2781,7 @@ struct mrsas_softc {
        LD_SPAN_INFO log_to_span[MAX_LOGICAL_DRIVES_EXT];
 
        u_int8_t secure_jbod_support;
+       u_int8_t use_seqnum_jbod_fp;
        u_int8_t max256vdSupport;
        u_int16_t fw_supported_vd_count;
        u_int16_t fw_supported_pd_count;

Modified: head/sys/dev/mrsas/mrsas_cam.c
==============================================================================
--- head/sys/dev/mrsas/mrsas_cam.c      Fri May 13 12:00:46 2016        
(r299666)
+++ head/sys/dev/mrsas/mrsas_cam.c      Fri May 13 12:05:02 2016        
(r299667)
@@ -65,11 +65,14 @@ int 
 mrsas_map_request(struct mrsas_softc *sc,
     struct mrsas_mpt_cmd *cmd, union ccb *ccb);
 int
-mrsas_build_ldio(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
+mrsas_build_ldio_rw(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
     union ccb *ccb);
 int
-mrsas_build_dcdb(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
-    union ccb *ccb, struct cam_sim *sim);
+mrsas_build_ldio_nonrw(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
+    union ccb *ccb);
+int
+mrsas_build_syspdio(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
+    union ccb *ccb, struct cam_sim *sim, u_int8_t fp_possible);
 int
 mrsas_setup_io(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
     union ccb *ccb, u_int32_t device_id,
@@ -415,6 +418,7 @@ mrsas_startio(struct mrsas_softc *sc, st
        struct ccb_hdr *ccb_h = &(ccb->ccb_h);
        struct ccb_scsiio *csio = &(ccb->csio);
        MRSAS_REQUEST_DESCRIPTOR_UNION *req_desc;
+       u_int8_t cmd_type;
 
        if ((csio->cdb_io.cdb_bytes[0]) == SYNCHRONIZE_CACHE) {
                ccb->ccb_h.status = CAM_REQ_CMP;
@@ -517,19 +521,44 @@ mrsas_startio(struct mrsas_softc *sc, st
        mtx_lock(&sc->raidmap_lock);
 
        /* Check for IO type READ-WRITE targeted for Logical Volume */
-       if (mrsas_find_io_type(sim, ccb) == READ_WRITE_LDIO) {
+       cmd_type = mrsas_find_io_type(sim, ccb);
+       switch (cmd_type) {
+       case READ_WRITE_LDIO:
                /* Build READ-WRITE IO for Logical Volume  */
-               if (mrsas_build_ldio(sc, cmd, ccb)) {
-                       device_printf(sc->mrsas_dev, "Build LDIO failed.\n");
+               if (mrsas_build_ldio_rw(sc, cmd, ccb)) {
+                       device_printf(sc->mrsas_dev, "Build RW LDIO failed.\n");
                        mtx_unlock(&sc->raidmap_lock);
                        return (1);
                }
-       } else {
-               if (mrsas_build_dcdb(sc, cmd, ccb, sim)) {
-                       device_printf(sc->mrsas_dev, "Build DCDB failed.\n");
+               break;
+       case NON_READ_WRITE_LDIO:
+               /* Build NON READ-WRITE IO for Logical Volume  */
+               if (mrsas_build_ldio_nonrw(sc, cmd, ccb)) {
+                       device_printf(sc->mrsas_dev, "Build NON-RW LDIO 
failed.\n");
                        mtx_unlock(&sc->raidmap_lock);
                        return (1);
                }
+               break;
+       case READ_WRITE_SYSPDIO:
+       case NON_READ_WRITE_SYSPDIO:
+               if (sc->secure_jbod_support &&
+                   (cmd_type == NON_READ_WRITE_SYSPDIO)) {
+                       /* Build NON-RW IO for JBOD */
+                       if (mrsas_build_syspdio(sc, cmd, ccb, sim, 0)) {
+                               device_printf(sc->mrsas_dev,
+                                   "Build SYSPDIO failed.\n");
+                               mtx_unlock(&sc->raidmap_lock);
+                               return (1);
+                       }
+               } else {
+                       /* Build RW IO for JBOD */
+                       if (mrsas_build_syspdio(sc, cmd, ccb, sim, 1)) {
+                               device_printf(sc->mrsas_dev,
+                                   "Build SYSPDIO failed.\n");
+                               mtx_unlock(&sc->raidmap_lock);
+                               return (1);
+                       }
+               }
        }
        mtx_unlock(&sc->raidmap_lock);
 
@@ -668,7 +697,7 @@ mrsas_get_request_desc(struct mrsas_soft
 }
 
 /*
- * mrsas_build_ldio:   Builds an LDIO command
+ * mrsas_build_ldio_rw:        Builds an LDIO command
  * input:                              Adapter instance soft state
  *                                             Pointer to command packet
  *                                             Pointer to CCB
@@ -677,7 +706,7 @@ mrsas_get_request_desc(struct mrsas_soft
  * built successfully, otherwise it returns a 1.
  */
 int
-mrsas_build_ldio(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
+mrsas_build_ldio_rw(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
     union ccb *ccb)
 {
        struct ccb_hdr *ccb_h = &(ccb->ccb_h);
@@ -879,83 +908,141 @@ mrsas_setup_io(struct mrsas_softc *sc, s
 }
 
 /*
- * mrsas_build_dcdb:   Builds an DCDB command
+ * mrsas_build_ldio_nonrw:     Builds an LDIO command
  * input:                              Adapter instance soft state
  *                                             Pointer to command packet
  *                                             Pointer to CCB
  *
- * This function builds the DCDB inquiry command.  It returns 0 if the command
- * is built successfully, otherwise it returns a 1.
+ * This function builds the LDIO command packet.  It returns 0 if the command 
is
+ * built successfully, otherwise it returns a 1.
  */
 int
-mrsas_build_dcdb(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
-    union ccb *ccb, struct cam_sim *sim)
+mrsas_build_ldio_nonrw(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
+    union ccb *ccb)
 {
        struct ccb_hdr *ccb_h = &(ccb->ccb_h);
        u_int32_t device_id;
-       MR_DRV_RAID_MAP_ALL *map_ptr;
        MRSAS_RAID_SCSI_IO_REQUEST *io_request;
 
        io_request = cmd->io_request;
        device_id = ccb_h->target_id;
-       map_ptr = sc->ld_drv_map[(sc->map_id & 1)];
 
-       /*
-         * Check if this is RW for system PD or
-         * it's a NON RW for sys PD and there is NO secure jbod FW support
-         */
-       if (cam_sim_bus(sim) == 1 &&
-           sc->pd_list[device_id].driveState == MR_PD_STATE_SYSTEM) {
+       /* FW path for LD Non-RW (SCSI management commands) */
+       io_request->Function = MRSAS_MPI2_FUNCTION_LD_IO_REQUEST;
+       io_request->DevHandle = device_id;
+       cmd->request_desc->SCSIIO.RequestFlags =
+           (MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO <<
+           MRSAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
 
-               io_request->DevHandle =
-                   map_ptr->raidMap.devHndlInfo[device_id].curDevHdl;
-               io_request->RaidContext.RAIDFlags =
-                   MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD <<
-                   MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT;
-               cmd->request_desc->SCSIIO.DevHandle = io_request->DevHandle;
-               cmd->request_desc->SCSIIO.MSIxIndex =
-                   sc->msix_vectors ? smp_processor_id() % sc->msix_vectors : 
0;
-
-               if (sc->secure_jbod_support && (mrsas_find_io_type(sim, ccb) == 
NON_READ_WRITE_SYSPDIO)) {
-                       /* system pd firmware path */
-                       io_request->Function = 
MRSAS_MPI2_FUNCTION_LD_IO_REQUEST;
-                       cmd->request_desc->SCSIIO.RequestFlags =
-                           (MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO << 
MRSAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
-               } else {
-                       /* system pd fast path */
-                       io_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
-                       io_request->RaidContext.timeoutValue = 
map_ptr->raidMap.fpPdIoTimeoutSec;
-                       io_request->RaidContext.regLockFlags = 0;
-                       io_request->RaidContext.regLockRowLBA = 0;
-                       io_request->RaidContext.regLockLength = 0;
-
-                       cmd->request_desc->SCSIIO.RequestFlags =
-                           (MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY <<
-                           MRSAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
+       io_request->RaidContext.VirtualDiskTgtId = device_id;
+       io_request->LUN[1] = ccb_h->target_lun & 0xF;
+       io_request->DataLength = cmd->length;
 
-                       /*
-                        * NOTE - For system pd RW cmds only IoFlags will be 
FAST_PATH
-                        * Because the NON RW cmds will now go via FW Queue
-                        * and not the Exception queue
-                        */
-                       if ((sc->device_id == MRSAS_INVADER) || (sc->device_id 
== MRSAS_FURY))
-                               io_request->IoFlags |= 
MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH;
+       if (mrsas_map_request(sc, cmd, ccb) == SUCCESS) {
+               if (cmd->sge_count > MRSAS_MAX_SGL) {
+                       device_printf(sc->mrsas_dev, "Error: sge_count (0x%x) 
exceeds"
+                           "max (0x%x) allowed\n", cmd->sge_count, 
sc->max_num_sge);
+                       return (1);
                }
+               io_request->RaidContext.numSGE = cmd->sge_count;
+       } else {
+               device_printf(sc->mrsas_dev, "Data map/load failed.\n");
+               return (1);
+       }
+       return (0);
+}
+
+/*
+ * mrsas_build_syspdio:        Builds an DCDB command
+ * input:                              Adapter instance soft state
+ *                                             Pointer to command packet
+ *                                             Pointer to CCB
+ *
+ * This function builds the DCDB inquiry command.  It returns 0 if the command
+ * is built successfully, otherwise it returns a 1.
+ */
+int
+mrsas_build_syspdio(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
+    union ccb *ccb, struct cam_sim *sim, u_int8_t fp_possible)
+{
+       struct ccb_hdr *ccb_h = &(ccb->ccb_h);
+       u_int32_t device_id;
+       MR_DRV_RAID_MAP_ALL *local_map_ptr;
+       MRSAS_RAID_SCSI_IO_REQUEST *io_request;
+       struct MR_PD_CFG_SEQ_NUM_SYNC *pd_sync;
+
+       pd_sync = (void *)sc->jbodmap_mem[(sc->pd_seq_map_id - 1) & 1];
+
+       io_request = cmd->io_request;
+       device_id = ccb_h->target_id;
+       local_map_ptr = sc->ld_drv_map[(sc->map_id & 1)];
+       io_request->RaidContext.RAIDFlags = MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD
+           << MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT;
+       io_request->RaidContext.regLockFlags = 0;
+       io_request->RaidContext.regLockRowLBA = 0;
+       io_request->RaidContext.regLockLength = 0;
+
+       /* If FW supports PD sequence number */
+       if (sc->use_seqnum_jbod_fp &&
+           sc->pd_list[device_id].driveType == 0x00) {
+               //printf("Using Drv seq num\n");
+               io_request->RaidContext.VirtualDiskTgtId = device_id + 255;
+               io_request->RaidContext.configSeqNum = 
pd_sync->seq[device_id].seqNum;
+               io_request->DevHandle = pd_sync->seq[device_id].devHandle;
+               io_request->RaidContext.regLockFlags |=
+                   (MR_RL_FLAGS_SEQ_NUM_ENABLE | 
MR_RL_FLAGS_GRANT_DESTINATION_CUDA);
+               io_request->RaidContext.Type = MPI2_TYPE_CUDA;
+               io_request->RaidContext.nseg = 0x1;
+       } else if (sc->fast_path_io) {
+               //printf("Using LD RAID map\n");
+               io_request->RaidContext.VirtualDiskTgtId = device_id;
+               io_request->RaidContext.configSeqNum = 0;
+               local_map_ptr = sc->ld_drv_map[(sc->map_id & 1)];
+               io_request->DevHandle =
+                   local_map_ptr->raidMap.devHndlInfo[device_id].curDevHdl;
        } else {
-               /* FW path for SysPD or LD Non-RW (SCSI management commands) */
+               //printf("Using FW PATH\n");
+               /* Want to send all IO via FW path */
+               io_request->RaidContext.VirtualDiskTgtId = device_id;
+               io_request->RaidContext.configSeqNum = 0;
+               io_request->DevHandle = 0xFFFF;
+       }
+
+       cmd->request_desc->SCSIIO.DevHandle = io_request->DevHandle;
+       cmd->request_desc->SCSIIO.MSIxIndex =
+           sc->msix_vectors ? smp_processor_id() % sc->msix_vectors : 0;
+
+       if (!fp_possible) {
+               /* system pd firmware path */
                io_request->Function = MRSAS_MPI2_FUNCTION_LD_IO_REQUEST;
-               io_request->DevHandle = device_id;
                cmd->request_desc->SCSIIO.RequestFlags =
                    (MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO <<
                    MRSAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
+               io_request->RaidContext.timeoutValue =
+                   local_map_ptr->raidMap.fpPdIoTimeoutSec;
+               io_request->RaidContext.VirtualDiskTgtId = device_id;
+       } else {
+               /* system pd fast path */
+               io_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
+               io_request->RaidContext.timeoutValue = 
local_map_ptr->raidMap.fpPdIoTimeoutSec;
+
+               /*
+                * NOTE - For system pd RW cmds only IoFlags will be FAST_PATH
+                * Because the NON RW cmds will now go via FW Queue
+                * and not the Exception queue
+                */
+               io_request->IoFlags |= 
MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH;
+
+               cmd->request_desc->SCSIIO.RequestFlags =
+                   (MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY <<
+                   MRSAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
        }
 
-       io_request->RaidContext.VirtualDiskTgtId = device_id;
        io_request->LUN[1] = ccb_h->target_lun & 0xF;
        io_request->DataLength = cmd->length;
 
        if (mrsas_map_request(sc, cmd, ccb) == SUCCESS) {
-               if (cmd->sge_count > sc->max_num_sge) {
+               if (cmd->sge_count > MRSAS_MAX_SGL) {
                        device_printf(sc->mrsas_dev, "Error: sge_count (0x%x) 
exceeds"
                            "max (0x%x) allowed\n", cmd->sge_count, 
sc->max_num_sge);
                        return (1);
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to