aboutsummaryrefslogtreecommitdiff
path: root/share/examples/scsi_target/scsi_cmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'share/examples/scsi_target/scsi_cmds.c')
-rw-r--r--share/examples/scsi_target/scsi_cmds.c109
1 files changed, 72 insertions, 37 deletions
diff --git a/share/examples/scsi_target/scsi_cmds.c b/share/examples/scsi_target/scsi_cmds.c
index bd23bedb6af6..8d5f14b5f550 100644
--- a/share/examples/scsi_target/scsi_cmds.c
+++ b/share/examples/scsi_target/scsi_cmds.c
@@ -35,6 +35,7 @@
#include <string.h>
#include <err.h>
#include <aio.h>
+#include <unistd.h>
#include <assert.h>
#include <sys/param.h>
#include <sys/types.h>
@@ -360,7 +361,7 @@ init_inquiry(u_int16_t req_flags, u_int16_t sim_flags)
/* Advertise only what the SIM can actually support */
req_flags &= sim_flags;
- scsi_ulto2b(req_flags, &inq->reserved[1]);
+ scsi_ulto2b(req_flags, &inq->spc2_flags);
inq->response_format = 2; /* SCSI2 Inquiry Format */
inq->additional_length = SHORT_INQUIRY_LENGTH -
@@ -496,21 +497,13 @@ tcmd_rdwr(struct ccb_accept_tio *atio, struct ccb_scsiio *ctio)
if ((a_descr->flags & CAM_DIR_IN) != 0) {
ret = start_io(atio, ctio, CAM_DIR_IN);
if (debug)
-#if __FreeBSD_version >= 500000
- warnx("Starting DIR_IN @%jd:%u",
-#else
- warnx("Starting DIR_IN @%lld:%u",
-#endif
- c_descr->offset, a_descr->targ_req);
+ warnx("Starting %p DIR_IN @" OFF_FMT ":%u",
+ a_descr, c_descr->offset, a_descr->targ_req);
} else {
ret = start_io(atio, ctio, CAM_DIR_OUT);
if (debug)
-#if __FreeBSD_version >= 500000
- warnx("Starting DIR_OUT @%jd:%u",
-#else
- warnx("Starting DIR_OUT @%lld:%u",
-#endif
- c_descr->offset, a_descr->init_req);
+ warnx("Starting %p DIR_OUT @" OFF_FMT ":%u",
+ a_descr, c_descr->offset, a_descr->init_req);
}
return (ret);
@@ -572,29 +565,17 @@ tcmd_rdwr_decode(struct ccb_accept_tio *atio, struct ccb_scsiio *ctio)
a_descr->total_len = count * sector_size;
if (a_descr->total_len == 0) {
if (debug)
-#if __FreeBSD_version >= 500000
- warnx("r/w 0 blocks @ blkno %ju", blkno);
-#else
- warnx("r/w 0 blocks @ blkno %llu", blkno);
-#endif
+ warnx("r/w 0 blocks @ blkno " OFF_FMT, blkno);
tcmd_null_ok(atio, ctio);
return (0);
} else if (cdb[0] == WRITE_6 || cdb[0] == WRITE_10) {
a_descr->flags |= CAM_DIR_OUT;
if (debug)
-#if __FreeBSD_version >= 500000
- warnx("write %u blocks @ blkno %ju", count, blkno);
-#else
- warnx("write %u blocks @ blkno %llu", count, blkno);
-#endif
+ warnx("write %u blocks @ blkno " OFF_FMT, count, blkno);
} else {
a_descr->flags |= CAM_DIR_IN;
if (debug)
-#if __FreeBSD_version >= 500000
- warnx("read %u blocks @ blkno %ju", count, blkno);
-#else
- warnx("read %u blocks @ blkno %llu", count, blkno);
-#endif
+ warnx("read %u blocks @ blkno " OFF_FMT, count, blkno);
}
return (1);
}
@@ -626,14 +607,41 @@ start_io(struct ccb_accept_tio *atio, struct ccb_scsiio *ctio, int dir)
/* If DIR_IN, start read from target, otherwise begin CTIO xfer. */
ret = 1;
if (dir == CAM_DIR_IN) {
- if (aio_read(&c_descr->aiocb) < 0)
- err(1, "aio_read"); /* XXX */
+ if (notaio) {
+ if (debug)
+ warnx("read sync %lud @ block " OFF_FMT,
+ (unsigned long)
+ (ctio->dxfer_len / sector_size),
+ c_descr->offset / sector_size);
+ if (lseek(c_descr->aiocb.aio_fildes,
+ c_descr->aiocb.aio_offset, SEEK_SET) < 0) {
+ perror("lseek");
+ err(1, "lseek");
+ }
+ if (read(c_descr->aiocb.aio_fildes,
+ (void *)c_descr->aiocb.aio_buf,
+ ctio->dxfer_len) != ctio->dxfer_len) {
+ err(1, "read");
+ }
+ } else {
+ if (debug)
+ warnx("read async %lud @ block " OFF_FMT,
+ (unsigned long)
+ (ctio->dxfer_len / sector_size),
+ c_descr->offset / sector_size);
+ if (aio_read(&c_descr->aiocb) < 0) {
+ err(1, "aio_read"); /* XXX */
+ }
+ }
a_descr->targ_req += ctio->dxfer_len;
+ /* if we're done, we can mark the CCB as to send status */
if (a_descr->targ_req == a_descr->total_len) {
ctio->ccb_h.flags |= CAM_SEND_STATUS;
ctio->scsi_status = SCSI_STATUS_OK;
ret = 0;
}
+ if (notaio)
+ tcmd_rdwr_done(atio, ctio, AIO_DONE);
} else {
if (a_descr->targ_ack == a_descr->total_len)
tcmd_null_ok(atio, ctio);
@@ -665,7 +673,7 @@ tcmd_rdwr_done(struct ccb_accept_tio *atio, struct ccb_scsiio *ctio,
switch (event) {
case AIO_DONE:
- if (aio_return(&c_descr->aiocb) < 0) {
+ if (!notaio && aio_return(&c_descr->aiocb) < 0) {
warn("aio_return error");
/* XXX */
tcmd_sense(ctio->init_id, ctio,
@@ -675,8 +683,12 @@ tcmd_rdwr_done(struct ccb_accept_tio *atio, struct ccb_scsiio *ctio,
}
a_descr->targ_ack += ctio->dxfer_len;
if ((a_descr->flags & CAM_DIR_IN) != 0) {
- if (debug)
- warnx("sending CTIO for AIO read");
+ if (debug) {
+ if (notaio)
+ warnx("sending CTIO for AIO read");
+ else
+ warnx("sending CTIO for sync read");
+ }
a_descr->init_req += ctio->dxfer_len;
send_ccb((union ccb *)ctio, /*priority*/1);
} else {
@@ -710,11 +722,34 @@ tcmd_rdwr_done(struct ccb_accept_tio *atio, struct ccb_scsiio *ctio,
a_descr->init_ack += ctio->dxfer_len;
if ((a_descr->flags & CAM_DIR_MASK) == CAM_DIR_OUT &&
ctio->dxfer_len > 0) {
- if (debug)
- warnx("sending AIO for CTIO write");
a_descr->targ_req += ctio->dxfer_len;
- if (aio_write(&c_descr->aiocb) < 0)
- err(1, "aio_write"); /* XXX */
+ if (notaio) {
+ if (debug)
+ warnx("write sync %lud @ block "
+ OFF_FMT, (unsigned long)
+ (ctio->dxfer_len / sector_size),
+ c_descr->offset / sector_size);
+ if (lseek(c_descr->aiocb.aio_fildes,
+ c_descr->aiocb.aio_offset, SEEK_SET) < 0) {
+ perror("lseek");
+ err(1, "lseek");
+ }
+ if (write(c_descr->aiocb.aio_fildes,
+ (void *) c_descr->aiocb.aio_buf,
+ ctio->dxfer_len) != ctio->dxfer_len) {
+ err(1, "write");
+ }
+ tcmd_rdwr_done(atio, ctio, AIO_DONE);
+ } else {
+ if (debug)
+ warnx("write async %lud @ block "
+ OFF_FMT, (unsigned long)
+ (ctio->dxfer_len / sector_size),
+ c_descr->offset / sector_size);
+ if (aio_write(&c_descr->aiocb) < 0) {
+ err(1, "aio_write"); /* XXX */
+ }
+ }
} else {
if (debug)
warnx("CTIO done freeing CTIO");