- 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. Sponsored by: iXsystems, inc. MFC after: 3 days
This commit is contained in:
parent
1d1143ec27
commit
5f8ad41c0d
@ -1488,7 +1488,7 @@ mfi_data_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
|
||||
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 *segs, int nsegs, int error)
|
||||
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 *segs, int nsegs, int error)
|
||||
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, struct mfi_command *cm)
|
||||
|
||||
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, caddr_t arg, int flag, struct thread *td
|
||||
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, caddr_t arg, int flag, struct thread *td
|
||||
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, caddr_t arg, int flag, struct thread *td
|
||||
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) {
|
||||
/* Native */
|
||||
error = copyin(ioc->mfi_sgl[i].iov_base,
|
||||
temp,
|
||||
ioc->mfi_sgl[i].iov_len);
|
||||
} else {
|
||||
void *temp_convert;
|
||||
/* 32bit */
|
||||
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);
|
||||
}
|
||||
#else
|
||||
error = copyin(ioc->mfi_sgl[i].iov_base,
|
||||
temp,
|
||||
ioc->mfi_sgl[i].iov_len);
|
||||
#endif
|
||||
/* Native */
|
||||
addr = ioc->mfi_sgl[i].iov_base;
|
||||
len = ioc->mfi_sgl[i].iov_len;
|
||||
#ifdef __amd64__
|
||||
} else {
|
||||
/* 32bit on 64bit */
|
||||
ioc32 = (struct mfi_ioc_packet32 *)ioc;
|
||||
addr = PTRIN(ioc32->mfi_sgl[i].iov_base);
|
||||
len = ioc32->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, caddr_t arg, int flag, struct thread *td
|
||||
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) {
|
||||
/* Native */
|
||||
error = copyout(temp,
|
||||
ioc->mfi_sgl[i].iov_base,
|
||||
ioc->mfi_sgl[i].iov_len);
|
||||
} else {
|
||||
void *temp_convert;
|
||||
/* 32bit */
|
||||
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);
|
||||
}
|
||||
#else
|
||||
error = copyout(temp,
|
||||
ioc->mfi_sgl[i].iov_base,
|
||||
ioc->mfi_sgl[i].iov_len);
|
||||
#endif
|
||||
/* Native */
|
||||
addr = ioc->mfi_sgl[i].iov_base;
|
||||
len = ioc->mfi_sgl[i].iov_len;
|
||||
#ifdef __amd64__
|
||||
} else {
|
||||
/* 32bit on 64bit */
|
||||
ioc32 = (struct mfi_ioc_packet32 *)ioc;
|
||||
addr = PTRIN(ioc32->mfi_sgl[i].iov_base);
|
||||
len = ioc32->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];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user