svn commit: r225918 - stable/9/sys/dev/mfi

Alexander Motin mav at FreeBSD.org
Sun Oct 2 12:15:15 UTC 2011


Author: mav
Date: Sun Oct  2 12:15:15 2011
New Revision: 225918
URL: http://svn.freebsd.org/changeset/base/225918

Log:
  MFC r225869:
  - Add special support for the MFI_CMD ioctl with MFI_CMD_STP command,
  used by present MegaCLI version. It has some special meaning for the
  first s/g list entry, while the main s/g list begins from the the second
  entry, and those lists should remain separate after loading to the
  busdma map.
   - Fix bug in 32bit ioctl compatibility shims when s/g list consists of
  more then on element.
  
  Approved by:	re (kib)

Modified:
  stable/9/sys/dev/mfi/mfi.c
  stable/9/sys/dev/mfi/mfivar.h
Directory Properties:
  stable/9/sys/   (props changed)
  stable/9/sys/amd64/include/xen/   (props changed)
  stable/9/sys/boot/   (props changed)
  stable/9/sys/boot/i386/efi/   (props changed)
  stable/9/sys/boot/ia64/efi/   (props changed)
  stable/9/sys/boot/ia64/ski/   (props changed)
  stable/9/sys/boot/powerpc/boot1.chrp/   (props changed)
  stable/9/sys/boot/powerpc/ofw/   (props changed)
  stable/9/sys/cddl/contrib/opensolaris/   (props changed)
  stable/9/sys/conf/   (props changed)
  stable/9/sys/contrib/dev/acpica/   (props changed)
  stable/9/sys/contrib/octeon-sdk/   (props changed)
  stable/9/sys/contrib/pf/   (props changed)
  stable/9/sys/contrib/x86emu/   (props changed)

Modified: stable/9/sys/dev/mfi/mfi.c
==============================================================================
--- stable/9/sys/dev/mfi/mfi.c	Sun Oct  2 11:13:28 2011	(r225917)
+++ stable/9/sys/dev/mfi/mfi.c	Sun Oct  2 12:15:15 2011	(r225918)
@@ -1488,7 +1488,7 @@ mfi_data_cb(void *arg, bus_dma_segment_t
 	struct mfi_command *cm;
 	union mfi_sgl *sgl;
 	struct mfi_softc *sc;
-	int i, dir;
+	int i, j, first, dir;
 
 	cm = (struct mfi_command *)arg;
 	sc = cm->cm_sc;
@@ -1502,19 +1502,33 @@ mfi_data_cb(void *arg, bus_dma_segment_t
 		return;
 	}
 
+	j = 0;
+	if (cm->cm_frame->header.cmd == MFI_CMD_STP) {
+		first = cm->cm_stp_len;
+		if ((sc->mfi_flags & MFI_FLAGS_SG64) == 0) {
+			sgl->sg32[j].addr = segs[0].ds_addr;
+			sgl->sg32[j++].len = first;
+		} else {
+			sgl->sg64[j].addr = segs[0].ds_addr;
+			sgl->sg64[j++].len = first;
+		}
+	} else
+		first = 0;
 	if ((sc->mfi_flags & MFI_FLAGS_SG64) == 0) {
 		for (i = 0; i < nsegs; i++) {
-			sgl->sg32[i].addr = segs[i].ds_addr;
-			sgl->sg32[i].len = segs[i].ds_len;
+			sgl->sg32[j].addr = segs[i].ds_addr + first;
+			sgl->sg32[j++].len = segs[i].ds_len - first;
+			first = 0;
 		}
 	} else {
 		for (i = 0; i < nsegs; i++) {
-			sgl->sg64[i].addr = segs[i].ds_addr;
-			sgl->sg64[i].len = segs[i].ds_len;
+			sgl->sg64[j].addr = segs[i].ds_addr + first;
+			sgl->sg64[j++].len = segs[i].ds_len - first;
+			first = 0;
 		}
 		hdr->flags |= MFI_FRAME_SGL64;
 	}
-	hdr->sg_count = nsegs;
+	hdr->sg_count = j;
 
 	dir = 0;
 	if (cm->cm_flags & MFI_CMD_DATAIN) {
@@ -1525,6 +1539,8 @@ mfi_data_cb(void *arg, bus_dma_segment_t
 		dir |= BUS_DMASYNC_PREWRITE;
 		hdr->flags |= MFI_FRAME_DIR_WRITE;
 	}
+	if (cm->cm_frame->header.cmd == MFI_CMD_STP)
+		dir |= BUS_DMASYNC_PREWRITE;
 	bus_dmamap_sync(sc->mfi_buffer_dmat, cm->cm_dmamap, dir);
 	cm->cm_flags |= MFI_CMD_MAPPED;
 
@@ -1602,7 +1618,8 @@ mfi_complete(struct mfi_softc *sc, struc
 
 	if ((cm->cm_flags & MFI_CMD_MAPPED) != 0) {
 		dir = 0;
-		if (cm->cm_flags & MFI_CMD_DATAIN)
+		if ((cm->cm_flags & MFI_CMD_DATAIN) ||
+		    (cm->cm_frame->header.cmd == MFI_CMD_STP))
 			dir |= BUS_DMASYNC_POSTREAD;
 		if (cm->cm_flags & MFI_CMD_DATAOUT)
 			dir |= BUS_DMASYNC_POSTWRITE;
@@ -1927,7 +1944,8 @@ mfi_ioctl(struct cdev *dev, u_long cmd, 
 	struct mfi_command *cm = NULL;
 	uint32_t context;
 	union mfi_sense_ptr sense_ptr;
-	uint8_t *data = NULL, *temp;
+	uint8_t *data = NULL, *temp, *addr;
+	size_t len;
 	int i;
 	struct mfi_ioc_passthru *iop = (struct mfi_ioc_passthru *)arg;
 #ifdef __amd64__
@@ -2024,6 +2042,21 @@ mfi_ioctl(struct cdev *dev, u_long cmd, 
 		if (cm->cm_flags == 0)
 			cm->cm_flags |= MFI_CMD_DATAIN | MFI_CMD_DATAOUT;
 		cm->cm_len = cm->cm_frame->header.data_len;
+		if (cm->cm_frame->header.cmd == MFI_CMD_STP) {
+#ifdef __amd64__
+			if (cmd == MFI_CMD) {
+#endif
+				/* Native */
+				cm->cm_stp_len = ioc->mfi_sgl[0].iov_len;
+#ifdef __amd64__
+			} else {
+				/* 32bit on 64bit */
+				ioc32 = (struct mfi_ioc_packet32 *)ioc;
+				cm->cm_stp_len = ioc32->mfi_sgl[0].iov_len;
+			}
+#endif
+			cm->cm_len += cm->cm_stp_len;
+		}
 		if (cm->cm_len &&
 		    (cm->cm_flags & (MFI_CMD_DATAIN | MFI_CMD_DATAOUT))) {
 			cm->cm_data = data = malloc(cm->cm_len, M_MFIBUF,
@@ -2040,35 +2073,30 @@ mfi_ioctl(struct cdev *dev, u_long cmd, 
 		cm->cm_frame->header.context = context;
 
 		temp = data;
-		if (cm->cm_flags & MFI_CMD_DATAOUT) {
+		if ((cm->cm_flags & MFI_CMD_DATAOUT) ||
+		    (cm->cm_frame->header.cmd == MFI_CMD_STP)) {
 			for (i = 0; i < ioc->mfi_sge_count; i++) {
 #ifdef __amd64__
 				if (cmd == MFI_CMD) {
+#endif
 					/* Native */
-					error = copyin(ioc->mfi_sgl[i].iov_base,
-					       temp,
-					       ioc->mfi_sgl[i].iov_len);
+					addr = ioc->mfi_sgl[i].iov_base;
+					len = ioc->mfi_sgl[i].iov_len;
+#ifdef __amd64__
 				} else {
-					void *temp_convert;
-					/* 32bit */
+					/* 32bit on 64bit */
 					ioc32 = (struct mfi_ioc_packet32 *)ioc;
-					temp_convert =
-					    PTRIN(ioc32->mfi_sgl[i].iov_base);
-					error = copyin(temp_convert,
-					       temp,
-					       ioc32->mfi_sgl[i].iov_len);
+					addr = PTRIN(ioc32->mfi_sgl[i].iov_base);
+					len = ioc32->mfi_sgl[i].iov_len;
 				}
-#else
-				error = copyin(ioc->mfi_sgl[i].iov_base,
-				       temp,
-				       ioc->mfi_sgl[i].iov_len);
 #endif
+				error = copyin(addr, temp, len);
 				if (error != 0) {
 					device_printf(sc->mfi_dev,
 					    "Copy in failed\n");
 					goto out;
 				}
-				temp = &temp[ioc->mfi_sgl[i].iov_len];
+				temp = &temp[len];
 			}
 		}
 
@@ -2098,35 +2126,30 @@ mfi_ioctl(struct cdev *dev, u_long cmd, 
 		mtx_unlock(&sc->mfi_io_lock);
 
 		temp = data;
-		if (cm->cm_flags & MFI_CMD_DATAIN) {
+		if ((cm->cm_flags & MFI_CMD_DATAIN) ||
+		    (cm->cm_frame->header.cmd == MFI_CMD_STP)) {
 			for (i = 0; i < ioc->mfi_sge_count; i++) {
 #ifdef __amd64__
 				if (cmd == MFI_CMD) {
+#endif
 					/* Native */
-					error = copyout(temp,
-						ioc->mfi_sgl[i].iov_base,
-						ioc->mfi_sgl[i].iov_len);
+					addr = ioc->mfi_sgl[i].iov_base;
+					len = ioc->mfi_sgl[i].iov_len;
+#ifdef __amd64__
 				} else {
-					void *temp_convert;
-					/* 32bit */
+					/* 32bit on 64bit */
 					ioc32 = (struct mfi_ioc_packet32 *)ioc;
-					temp_convert =
-					    PTRIN(ioc32->mfi_sgl[i].iov_base);
-					error = copyout(temp,
-						temp_convert,
-						ioc32->mfi_sgl[i].iov_len);
+					addr = PTRIN(ioc32->mfi_sgl[i].iov_base);
+					len = ioc32->mfi_sgl[i].iov_len;
 				}
-#else
-				error = copyout(temp,
-					ioc->mfi_sgl[i].iov_base,
-					ioc->mfi_sgl[i].iov_len);
 #endif
+				error = copyout(temp, addr, len);
 				if (error != 0) {
 					device_printf(sc->mfi_dev,
 					    "Copy out failed\n");
 					goto out;
 				}
-				temp = &temp[ioc->mfi_sgl[i].iov_len];
+				temp = &temp[len];
 			}
 		}
 

Modified: stable/9/sys/dev/mfi/mfivar.h
==============================================================================
--- stable/9/sys/dev/mfi/mfivar.h	Sun Oct  2 11:13:28 2011	(r225917)
+++ stable/9/sys/dev/mfi/mfivar.h	Sun Oct  2 12:15:15 2011	(r225918)
@@ -87,6 +87,7 @@ struct mfi_command {
 	union mfi_sgl		*cm_sg;
 	void			*cm_data;
 	int			cm_len;
+	int			cm_stp_len;
 	int			cm_total_frame_size;
 	int			cm_extra_frames;
 	int			cm_flags;


More information about the svn-src-stable-9 mailing list