Date: Sun, 2 Oct 2011 12:18:06 +0000 (UTC) From: Alexander Motin <mav@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: svn commit: r225919 - stable/8/sys/dev/mfi Message-ID: <201110021218.p92CI6vk063290@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mav Date: Sun Oct 2 12:18:06 2011 New Revision: 225919 URL: http://svn.freebsd.org/changeset/base/225919 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. Modified: stable/8/sys/dev/mfi/mfi.c stable/8/sys/dev/mfi/mfivar.h Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) Modified: stable/8/sys/dev/mfi/mfi.c ============================================================================== --- stable/8/sys/dev/mfi/mfi.c Sun Oct 2 12:15:15 2011 (r225918) +++ stable/8/sys/dev/mfi/mfi.c Sun Oct 2 12:18:06 2011 (r225919) @@ -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/8/sys/dev/mfi/mfivar.h ============================================================================== --- stable/8/sys/dev/mfi/mfivar.h Sun Oct 2 12:15:15 2011 (r225918) +++ stable/8/sys/dev/mfi/mfivar.h Sun Oct 2 12:18:06 2011 (r225919) @@ -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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201110021218.p92CI6vk063290>