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