Add under-/overrun support to IOCTL and CAM SIM frontends.
MFC after: 1 week
This commit is contained in:
parent
f319059631
commit
953f538e0e
@ -304,10 +304,6 @@ cfcs_datamove(union ctl_io *io)
|
||||
int ctl_watermark, cam_watermark;
|
||||
int i, j;
|
||||
|
||||
|
||||
cam_sg_offset = 0;
|
||||
cam_sg_start = 0;
|
||||
|
||||
ccb = io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr;
|
||||
|
||||
/*
|
||||
@ -330,6 +326,8 @@ cfcs_datamove(union ctl_io *io)
|
||||
|
||||
cam_sglist = (bus_dma_segment_t *)ccb->csio.data_ptr;
|
||||
cam_sg_count = ccb->csio.sglist_cnt;
|
||||
cam_sg_start = cam_sg_count;
|
||||
cam_sg_offset = 0;
|
||||
|
||||
for (i = 0, len_seen = 0; i < cam_sg_count; i++) {
|
||||
if ((len_seen + cam_sglist[i].ds_len) >=
|
||||
@ -422,9 +420,20 @@ cfcs_datamove(union ctl_io *io)
|
||||
|
||||
io->scsiio.ext_data_filled += len_copied;
|
||||
|
||||
/*
|
||||
* Report write underflow as error, since CTL and backends don't
|
||||
* really support it.
|
||||
*/
|
||||
if ((io->io_hdr.flags & CTL_FLAG_DATA_MASK) == CTL_FLAG_DATA_OUT &&
|
||||
j < ctl_sg_count) {
|
||||
io->io_hdr.port_status = 43;
|
||||
} else
|
||||
|
||||
if ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_SUCCESS) {
|
||||
io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr = NULL;
|
||||
io->io_hdr.flags |= CTL_FLAG_STATUS_SENT;
|
||||
ccb->csio.resid = ccb->csio.dxfer_len -
|
||||
io->scsiio.ext_data_filled;
|
||||
ccb->ccb_h.status &= ~CAM_STATUS_MASK;
|
||||
ccb->ccb_h.status |= CAM_REQ_CMP;
|
||||
xpt_done(ccb);
|
||||
@ -453,6 +462,10 @@ cfcs_done(union ctl_io *io)
|
||||
/*
|
||||
* Translate CTL status to CAM status.
|
||||
*/
|
||||
if (ccb->ccb_h.func_code == XPT_SCSI_IO) {
|
||||
ccb->csio.resid = ccb->csio.dxfer_len -
|
||||
io->scsiio.ext_data_filled;
|
||||
}
|
||||
ccb->ccb_h.status &= ~CAM_STATUS_MASK;
|
||||
switch (io->io_hdr.status & CTL_STATUS_MASK) {
|
||||
case CTL_SUCCESS:
|
||||
|
@ -143,16 +143,13 @@ ctl_ioctl_do_datamove(struct ctl_scsiio *ctsio)
|
||||
int ext_sglist_malloced;
|
||||
int i, j;
|
||||
|
||||
ext_sglist_malloced = 0;
|
||||
ext_sg_start = 0;
|
||||
ext_offset = 0;
|
||||
|
||||
CTL_DEBUG_PRINT(("ctl_ioctl_do_datamove\n"));
|
||||
|
||||
/*
|
||||
* If this flag is set, fake the data transfer.
|
||||
*/
|
||||
if (ctsio->io_hdr.flags & CTL_FLAG_NO_DATAMOVE) {
|
||||
ext_sglist_malloced = 0;
|
||||
ctsio->ext_data_filled = ctsio->ext_data_len;
|
||||
goto bailout;
|
||||
}
|
||||
@ -165,7 +162,6 @@ ctl_ioctl_do_datamove(struct ctl_scsiio *ctsio)
|
||||
int len_seen;
|
||||
|
||||
ext_sglen = ctsio->ext_sg_entries * sizeof(*ext_sglist);
|
||||
|
||||
ext_sglist = (struct ctl_sg_entry *)malloc(ext_sglen, M_CTL,
|
||||
M_WAITOK);
|
||||
ext_sglist_malloced = 1;
|
||||
@ -174,6 +170,8 @@ ctl_ioctl_do_datamove(struct ctl_scsiio *ctsio)
|
||||
goto bailout;
|
||||
}
|
||||
ext_sg_entries = ctsio->ext_sg_entries;
|
||||
ext_sg_start = ext_sg_entries;
|
||||
ext_offset = 0;
|
||||
len_seen = 0;
|
||||
for (i = 0; i < ext_sg_entries; i++) {
|
||||
if ((len_seen + ext_sglist[i].len) >=
|
||||
@ -186,6 +184,7 @@ ctl_ioctl_do_datamove(struct ctl_scsiio *ctsio)
|
||||
}
|
||||
} else {
|
||||
ext_sglist = &ext_entry;
|
||||
ext_sglist_malloced = 0;
|
||||
ext_sglist->addr = ctsio->ext_data_ptr;
|
||||
ext_sglist->len = ctsio->ext_data_len;
|
||||
ext_sg_entries = 1;
|
||||
@ -203,7 +202,6 @@ ctl_ioctl_do_datamove(struct ctl_scsiio *ctsio)
|
||||
kern_sg_entries = 1;
|
||||
}
|
||||
|
||||
|
||||
kern_watermark = 0;
|
||||
ext_watermark = ext_offset;
|
||||
len_copied = 0;
|
||||
@ -274,10 +272,16 @@ ctl_ioctl_do_datamove(struct ctl_scsiio *ctsio)
|
||||
"kern_data_len = %d\n", ctsio->ext_data_len,
|
||||
ctsio->kern_data_len));
|
||||
|
||||
/*
|
||||
* Report write underflow as error, since CTL and backends don't
|
||||
* really support it.
|
||||
*/
|
||||
if ((ctsio->io_hdr.flags & CTL_FLAG_DATA_MASK) == CTL_FLAG_DATA_OUT &&
|
||||
j < kern_sg_entries) {
|
||||
ctsio->io_hdr.port_status = 43;
|
||||
}
|
||||
|
||||
/* XXX KDM set residual?? */
|
||||
bailout:
|
||||
|
||||
if (ext_sglist_malloced != 0)
|
||||
free(ext_sglist, M_CTL);
|
||||
|
||||
@ -397,7 +401,7 @@ ctl_ioctl_io(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
|
||||
struct thread *td)
|
||||
{
|
||||
union ctl_io *io;
|
||||
void *pool_tmp;
|
||||
void *pool_tmp, *sc_tmp;
|
||||
int retval = 0;
|
||||
|
||||
/*
|
||||
@ -414,8 +418,10 @@ ctl_ioctl_io(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
|
||||
* spammed by the user's ctl_io.
|
||||
*/
|
||||
pool_tmp = io->io_hdr.pool;
|
||||
sc_tmp = CTL_SOFTC(io);
|
||||
memcpy(io, (void *)addr, sizeof(*io));
|
||||
io->io_hdr.pool = pool_tmp;
|
||||
CTL_SOFTC(io) = sc_tmp;
|
||||
|
||||
/*
|
||||
* No status yet, so make sure the status is set properly.
|
||||
|
Loading…
Reference in New Issue
Block a user