Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 13 May 2016 12:12:09 +0000 (UTC)
From:      Kashyap D Desai <kadesai@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r299668 - head/sys/dev/mrsas
Message-ID:  <201605131212.u4DCC96Z031710@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kadesai
Date: Fri May 13 12:12:09 2016
New Revision: 299668
URL: https://svnweb.freebsd.org/changeset/base/299668

Log:
  This patch implements driver support for 1MB IO size.
  
  NOTE:
  The FreeBSD system currently restricts the MAX IO size to MAXPHYS which
  in turn is 128KB. We tested the 1MB IO by converting the MAXPHYS to 1MB.
  
  Following is the mail reference:
  http://lists.freebsd.org/pipermail/freebsd-scsi/2015-January/006568.html
  
  Submitted by:   Sumit Saxena <sumit.saxena@broadcom.com>
  Reviewed by:    Kashyap Desai <Kashyap.Desai@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:05:02 2016	(r299667)
+++ head/sys/dev/mrsas/mrsas.c	Fri May 13 12:12:09 2016	(r299668)
@@ -1703,9 +1703,9 @@ mrsas_alloc_mem(struct mrsas_softc *sc)
 	    BUS_SPACE_MAXADDR,		/* lowaddr */
 	    BUS_SPACE_MAXADDR,		/* highaddr */
 	    NULL, NULL,			/* filter, filterarg */
-	    MRSAS_MAX_IO_SIZE,		/* maxsize */
-	    MRSAS_MAX_SGL,		/* nsegments */
-	    MRSAS_MAX_IO_SIZE,		/* maxsegsize */
+	    MAXPHYS,			/* maxsize */
+	    sc->max_num_sge,		/* nsegments */
+	    MAXPHYS,			/* maxsegsize */
 	    0,				/* flags */
 	    NULL, NULL,			/* lockfunc, lockarg */
 	    &sc->mrsas_parent_tag	/* tag */
@@ -1902,9 +1902,9 @@ mrsas_alloc_mem(struct mrsas_softc *sc)
 	    BUS_SPACE_MAXADDR,
 	    BUS_SPACE_MAXADDR,
 	    NULL, NULL,
-	    MRSAS_MAX_IO_SIZE,
-	    MRSAS_MAX_SGL,
-	    MRSAS_MAX_IO_SIZE,
+	    MAXPHYS,
+	    sc->max_num_sge,		/* nsegments */
+	    MAXPHYS,
 	    BUS_DMA_ALLOCNOW,
 	    busdma_lock_mutex,
 	    &sc->io_lock,
@@ -2248,7 +2248,7 @@ int
 mrsas_init_adapter(struct mrsas_softc *sc)
 {
 	uint32_t status;
-	u_int32_t max_cmd;
+	u_int32_t max_cmd, scratch_pad_2;
 	int ret;
 	int i = 0;
 
@@ -2267,13 +2267,33 @@ mrsas_init_adapter(struct mrsas_softc *s
 	sc->request_alloc_sz = sizeof(MRSAS_REQUEST_DESCRIPTOR_UNION) * max_cmd;
 	sc->reply_alloc_sz = sizeof(MPI2_REPLY_DESCRIPTORS_UNION) * (sc->reply_q_depth);
 	sc->io_frames_alloc_sz = MRSAS_MPI2_RAID_DEFAULT_IO_FRAME_SIZE + (MRSAS_MPI2_RAID_DEFAULT_IO_FRAME_SIZE * (max_cmd + 1));
-	sc->chain_frames_alloc_sz = 1024 * max_cmd;
+	scratch_pad_2 = mrsas_read_reg(sc, offsetof(mrsas_reg_set,
+	    outbound_scratch_pad_2));
+	/*
+	 * If scratch_pad_2 & MEGASAS_MAX_CHAIN_SIZE_UNITS_MASK is set,
+	 * Firmware support extended IO chain frame which is 4 time more
+	 * than legacy Firmware. Legacy Firmware - Frame size is (8 * 128) =
+	 * 1K 1M IO Firmware  - Frame size is (8 * 128 * 4)  = 4K
+	 */
+	if (scratch_pad_2 & MEGASAS_MAX_CHAIN_SIZE_UNITS_MASK)
+		sc->max_chain_frame_sz =
+		    ((scratch_pad_2 & MEGASAS_MAX_CHAIN_SIZE_MASK) >> 5)
+		    * MEGASAS_1MB_IO;
+	else
+		sc->max_chain_frame_sz =
+		    ((scratch_pad_2 & MEGASAS_MAX_CHAIN_SIZE_MASK) >> 5)
+		    * MEGASAS_256K_IO;
+
+	sc->chain_frames_alloc_sz = sc->max_chain_frame_sz * max_cmd;
 	sc->max_sge_in_main_msg = (MRSAS_MPI2_RAID_DEFAULT_IO_FRAME_SIZE -
 	    offsetof(MRSAS_RAID_SCSI_IO_REQUEST, SGL)) / 16;
 
-	sc->max_sge_in_chain = MRSAS_MAX_SZ_CHAIN_FRAME / sizeof(MPI2_SGE_IO_UNION);
+	sc->max_sge_in_chain = sc->max_chain_frame_sz / sizeof(MPI2_SGE_IO_UNION);
 	sc->max_num_sge = sc->max_sge_in_main_msg + sc->max_sge_in_chain - 2;
 
+	mrsas_dprint(sc, MRSAS_INFO, "Avago Debug: MAX sge 0x%X MAX chain frame size 0x%X \n",
+	    sc->max_num_sge, sc->max_chain_frame_sz);
+
 	/* Used for pass thru MFI frame (DCMD) */
 	sc->chain_offset_mfi_pthru = offsetof(MRSAS_RAID_SCSI_IO_REQUEST, SGL) / 16;
 
@@ -2411,6 +2431,8 @@ mrsas_ioc_init(struct mrsas_softc *sc)
 	init_frame->driver_operations.mfi_capabilities.support_ndrive_r1_lb = 1;
 	init_frame->driver_operations.mfi_capabilities.support_max_255lds = 1;
 	init_frame->driver_operations.mfi_capabilities.security_protocol_cmds_fw = 1;
+	if (sc->max_chain_frame_sz > MEGASAS_CHAIN_FRAME_SZ_MIN)
+		init_frame->driver_operations.mfi_capabilities.support_ext_io_size = 1;
 	phys_addr = (bus_addr_t)sc->ioc_init_phys_mem + 1024;
 	init_frame->queue_info_new_phys_addr_lo = phys_addr;
 	init_frame->data_xfer_len = sizeof(Mpi2IOCInitRequest_t);
@@ -2513,7 +2535,7 @@ mrsas_alloc_mpt_cmds(struct mrsas_softc 
 	for (i = 0; i < max_cmd; i++) {
 		cmd = sc->mpt_cmd_list[i];
 		offset = MRSAS_MPI2_RAID_DEFAULT_IO_FRAME_SIZE * i;
-		chain_offset = 1024 * i;
+		chain_offset = sc->max_chain_frame_sz * i;
 		sense_offset = MRSAS_SENSE_LEN * i;
 		memset(cmd, 0, sizeof(struct mrsas_mpt_cmd));
 		cmd->index = i + 1;
@@ -3447,7 +3469,7 @@ mrsas_build_mptmfi_passthru(struct mrsas
 	mpi25_ieee_chain->Flags = IEEE_SGE_FLAGS_CHAIN_ELEMENT |
 	    MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR;
 
-	mpi25_ieee_chain->Length = MRSAS_MAX_SZ_CHAIN_FRAME;
+	mpi25_ieee_chain->Length = sc->max_chain_frame_sz;
 
 	return (0);
 }

Modified: head/sys/dev/mrsas/mrsas.h
==============================================================================
--- head/sys/dev/mrsas/mrsas.h	Fri May 13 12:05:02 2016	(r299667)
+++ head/sys/dev/mrsas/mrsas.h	Fri May 13 12:12:09 2016	(r299668)
@@ -166,7 +166,9 @@ typedef struct _RAID_CONTEXT {
 	u_int8_t numSGE;
 	u_int16_t configSeqNum;
 	u_int8_t spanArm;
-	u_int8_t resvd2[3];
+	u_int8_t priority;		/* 0x1D MR_PRIORITY_RANGE */
+	u_int8_t numSGEExt;		/* 0x1E 1M IO support */
+	u_int8_t resvd2;		/* 0x1F */
 }	RAID_CONTEXT;
 
 
@@ -1240,7 +1242,7 @@ enum MR_EVT_ARGS {
 /*
  * Thunderbolt (and later) Defines
  */
-#define	MRSAS_MAX_SZ_CHAIN_FRAME					1024
+#define	MEGASAS_CHAIN_FRAME_SZ_MIN					1024
 #define	MFI_FUSION_ENABLE_INTERRUPT_MASK			(0x00000009)
 #define	MRSAS_MPI2_RAID_DEFAULT_IO_FRAME_SIZE		256
 #define	MRSAS_MPI2_FUNCTION_PASSTHRU_IO_REQUEST		0xF0
@@ -1318,10 +1320,13 @@ typedef enum _REGION_TYPE {
 #define	MRSAS_SCSI_MAX_CMDS				8
 #define	MRSAS_SCSI_MAX_CDB_LEN			16
 #define	MRSAS_SCSI_SENSE_BUFFERSIZE		96
-#define	MRSAS_MAX_SGL					70
-#define	MRSAS_MAX_IO_SIZE				(256 * 1024)
 #define	MRSAS_INTERNAL_CMDS				32
 
+#define	MEGASAS_MAX_CHAIN_SIZE_UNITS_MASK	0x400000
+#define	MEGASAS_MAX_CHAIN_SIZE_MASK		0x3E0
+#define	MEGASAS_256K_IO					128
+#define	MEGASAS_1MB_IO					(MEGASAS_256K_IO * 4)
+
 /* Request types */
 #define	MRSAS_REQ_TYPE_INTERNAL_CMD		0x0
 #define	MRSAS_REQ_TYPE_AEN_FETCH		0x1
@@ -2023,7 +2028,9 @@ typedef union _MFI_CAPABILITIES {
 		u_int32_t support_ndrive_r1_lb:1;
 		u_int32_t support_core_affinity:1;
 		u_int32_t security_protocol_cmds_fw:1;
-		u_int32_t reserved:25;
+		u_int32_t support_ext_queue_depth:1;
+		u_int32_t support_ext_io_size:1;
+		u_int32_t reserved:23;
 	}	mfi_capabilities;
 	u_int32_t reg;
 }	MFI_CAPABILITIES;
@@ -2697,6 +2704,7 @@ struct mrsas_softc {
 	int	msix_enable;
 	uint32_t msix_reg_offset[16];
 	uint8_t	mask_interrupts;
+	uint16_t max_chain_frame_sz;
 	struct mrsas_mpt_cmd **mpt_cmd_list;
 	struct mrsas_mfi_cmd **mfi_cmd_list;
 	TAILQ_HEAD(, mrsas_mpt_cmd) mrsas_mpt_cmd_list_head;

Modified: head/sys/dev/mrsas/mrsas_cam.c
==============================================================================
--- head/sys/dev/mrsas/mrsas_cam.c	Fri May 13 12:05:02 2016	(r299667)
+++ head/sys/dev/mrsas/mrsas_cam.c	Fri May 13 12:12:09 2016	(r299668)
@@ -344,7 +344,7 @@ mrsas_action(struct cam_sim *sim, union 
 			else
 				ccb->cpi.max_target = MRSAS_MAX_LD_IDS - 1;
 #if (__FreeBSD_version > 704000)
-			ccb->cpi.maxio = MRSAS_MAX_IO_SIZE;
+			ccb->cpi.maxio = sc->max_num_sge * MRSAS_PAGE_SIZE;
 #endif
 			ccb->ccb_h.status = CAM_REQ_CMP;
 			xpt_done(ccb);
@@ -462,7 +462,7 @@ mrsas_startio(struct mrsas_softc *sc, st
 		ccb_h->status = CAM_REQ_INVALID;
 		goto done;
 	case CAM_DATA_VADDR:
-		if (csio->dxfer_len > MRSAS_MAX_IO_SIZE) {
+		if (csio->dxfer_len > (sc->max_num_sge * MRSAS_PAGE_SIZE)) {
 			mrsas_release_mpt_cmd(cmd);
 			ccb_h->status = CAM_REQ_TOO_BIG;
 			goto done;
@@ -472,6 +472,11 @@ mrsas_startio(struct mrsas_softc *sc, st
 			cmd->data = csio->data_ptr;
 		break;
 	case CAM_DATA_BIO:
+		if (csio->dxfer_len > (sc->max_num_sge * MRSAS_PAGE_SIZE)) {
+			mrsas_release_mpt_cmd(cmd);
+			ccb_h->status = CAM_REQ_TOO_BIG;
+			goto done;
+		}
 		cmd->length = csio->dxfer_len;
 		if (cmd->length)
 			cmd->data = csio->data_ptr;
@@ -483,7 +488,7 @@ mrsas_startio(struct mrsas_softc *sc, st
 #else
 	if (!(ccb_h->flags & CAM_DATA_PHYS)) {	/* Virtual data address */
 		if (!(ccb_h->flags & CAM_SCATTER_VALID)) {
-			if (csio->dxfer_len > MRSAS_MAX_IO_SIZE) {
+			if (csio->dxfer_len > (sc->max_num_sge * MRSAS_PAGE_SIZE)) {
 				mrsas_release_mpt_cmd(cmd);
 				ccb_h->status = CAM_REQ_TOO_BIG;
 				goto done;
@@ -730,12 +735,18 @@ mrsas_build_ldio_rw(struct mrsas_softc *
 	io_request->DataLength = cmd->length;
 
 	if (mrsas_map_request(sc, cmd, ccb) == SUCCESS) {
-		if (cmd->sge_count > MRSAS_MAX_SGL) {
+		if (cmd->sge_count > sc->max_num_sge) {
 			device_printf(sc->mrsas_dev, "Error: sge_count (0x%x) exceeds"
 			    "max (0x%x) allowed\n", cmd->sge_count, sc->max_num_sge);
 			return (FAIL);
 		}
+		/*
+		 * numSGE store lower 8 bit of sge_count. numSGEExt store
+		 * higher 8 bit of sge_count
+		 */
 		io_request->RaidContext.numSGE = cmd->sge_count;
+		io_request->RaidContext.numSGEExt = (uint8_t)(cmd->sge_count >> 8);
+
 	} else {
 		device_printf(sc->mrsas_dev, "Data map/load failed.\n");
 		return (FAIL);
@@ -939,12 +950,17 @@ mrsas_build_ldio_nonrw(struct mrsas_soft
 	io_request->DataLength = cmd->length;
 
 	if (mrsas_map_request(sc, cmd, ccb) == SUCCESS) {
-		if (cmd->sge_count > MRSAS_MAX_SGL) {
+		if (cmd->sge_count > sc->max_num_sge) {
 			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);
 		}
+		/*
+		 * numSGE store lower 8 bit of sge_count. numSGEExt store
+		 * higher 8 bit of sge_count
+		 */
 		io_request->RaidContext.numSGE = cmd->sge_count;
+		io_request->RaidContext.numSGEExt = (uint8_t)(cmd->sge_count >> 8);
 	} else {
 		device_printf(sc->mrsas_dev, "Data map/load failed.\n");
 		return (1);
@@ -1042,12 +1058,17 @@ mrsas_build_syspdio(struct mrsas_softc *
 	io_request->DataLength = cmd->length;
 
 	if (mrsas_map_request(sc, cmd, ccb) == SUCCESS) {
-		if (cmd->sge_count > MRSAS_MAX_SGL) {
+		if (cmd->sge_count > sc->max_num_sge) {
 			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);
 		}
+		/*
+		 * numSGE store lower 8 bit of sge_count. numSGEExt store
+		 * higher 8 bit of sge_count
+		 */
 		io_request->RaidContext.numSGE = cmd->sge_count;
+		io_request->RaidContext.numSGEExt = (uint8_t)(cmd->sge_count >> 8);
 	} else {
 		device_printf(sc->mrsas_dev, "Data map/load failed.\n");
 		return (1);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201605131212.u4DCC96Z031710>