svn commit: r299667 - head/sys/dev/mrsas

Kashyap D Desai kadesai at FreeBSD.org
Fri May 13 12:05:04 UTC 2016


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.saxena at broadcom.com>
  Reviewed by:    Kashyap Desai <Kashyap.Desai at 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);


More information about the svn-src-all mailing list