diff options
Diffstat (limited to 'share/examples/scsi_target/scsi_cmds.c')
-rw-r--r-- | share/examples/scsi_target/scsi_cmds.c | 109 |
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"); |