diff options
author | Hidetoshi Shimokawa <simokawa@FreeBSD.org> | 2003-10-18 04:54:08 +0000 |
---|---|---|
committer | Hidetoshi Shimokawa <simokawa@FreeBSD.org> | 2003-10-18 04:54:08 +0000 |
commit | 068d70bad8eb8e154124d8cf3fda87bd180b3073 (patch) | |
tree | 7dfef19d5a11887c9625cdc237ce0b3e9547bff4 /share/examples/scsi_target | |
parent | dae6d925a2fb414a44ce35495604fb6f237ef25e (diff) |
- Enable 16byte commands.
- Fix printf warnings on 64bit architectures.
- Accept 'k', 'm' and etc. for -s option.
Reviewed by: njl
Notes
Notes:
svn path=/head/; revision=121184
Diffstat (limited to 'share/examples/scsi_target')
-rw-r--r-- | share/examples/scsi_target/scsi_cmds.c | 115 | ||||
-rw-r--r-- | share/examples/scsi_target/scsi_target.8 | 11 | ||||
-rw-r--r-- | share/examples/scsi_target/scsi_target.c | 42 | ||||
-rw-r--r-- | share/examples/scsi_target/scsi_target.h | 10 |
4 files changed, 159 insertions, 19 deletions
diff --git a/share/examples/scsi_target/scsi_cmds.c b/share/examples/scsi_target/scsi_cmds.c index 331578ff29a8..efdb35ee8bb4 100644 --- a/share/examples/scsi_target/scsi_cmds.c +++ b/share/examples/scsi_target/scsi_cmds.c @@ -36,6 +36,7 @@ #include <err.h> #include <aio.h> #include <assert.h> +#include <sys/param.h> #include <sys/types.h> #include <cam/cam.h> @@ -58,6 +59,9 @@ struct targ_cdb_handlers { static targ_start_func tcmd_inquiry; static targ_start_func tcmd_req_sense; static targ_start_func tcmd_rd_cap; +#ifdef READ_16 +static targ_start_func tcmd_rd_cap16; +#endif static targ_start_func tcmd_rdwr; static targ_start_func tcmd_rdwr_decode; static targ_done_func tcmd_rdwr_done; @@ -83,13 +87,18 @@ static struct targ_cdb_handlers cdb_handlers[] = { { SYNCHRONIZE_CACHE, tcmd_null_ok, NULL }, { MODE_SENSE_6, tcmd_illegal_req, NULL }, { MODE_SELECT_6, tcmd_illegal_req, NULL }, +#ifdef READ_16 + { READ_16, tcmd_rdwr, tcmd_rdwr_done }, + { WRITE_16, tcmd_rdwr, tcmd_rdwr_done }, + { SERVICE_ACTION_IN, tcmd_rd_cap16, NULL }, +#endif { ILLEGAL_CDB, NULL, NULL } }; static struct scsi_inquiry_data inq_data; static struct initiator_state istates[MAX_INITIATORS]; extern int debug; -extern u_int32_t volume_size; +extern uint64_t volume_size; extern size_t sector_size; extern size_t buf_size; @@ -398,17 +407,55 @@ tcmd_rd_cap(struct ccb_accept_tio *atio, struct ccb_scsiio *ctio) { struct scsi_read_capacity_data *srp; struct atio_descr *a_descr; + uint32_t vsize; a_descr = (struct atio_descr *)atio->ccb_h.targ_descr; srp = (struct scsi_read_capacity_data *)ctio->data_ptr; + if (volume_size > 0xffffffff) + vsize = 0xffffffff; + else + vsize = (uint32_t)(volume_size - 1); + if (debug) { cdb_debug(a_descr->cdb, "READ CAP from %u (%u, %u): ", + atio->init_id, vsize, sector_size); + } + + bzero(srp, sizeof(*srp)); + scsi_ulto4b(vsize, srp->addr); + scsi_ulto4b(sector_size, srp->length); + + ctio->dxfer_len = sizeof(*srp); + ctio->ccb_h.flags |= CAM_DIR_IN | CAM_SEND_STATUS; + ctio->scsi_status = SCSI_STATUS_OK; + return (0); +} + +#ifdef READ_16 +static int +tcmd_rd_cap16(struct ccb_accept_tio *atio, struct ccb_scsiio *ctio) +{ + struct scsi_read_capacity_16 *scsi_cmd; + struct scsi_read_capacity_data_long *srp; + struct atio_descr *a_descr; + + a_descr = (struct atio_descr *)atio->ccb_h.targ_descr; + scsi_cmd = (struct scsi_read_capacity_16 *)a_descr->cdb; + srp = (struct scsi_read_capacity_data_long *)ctio->data_ptr; + + if (scsi_cmd->service_action != SRC16_SERVICE_ACTION) { + tcmd_illegal_req(atio, ctio); + return (0); + } + + if (debug) { + cdb_debug(a_descr->cdb, "READ CAP16 from %u (%u, %u): ", atio->init_id, volume_size - 1, sector_size); } bzero(srp, sizeof(*srp)); - scsi_ulto4b(volume_size - 1, srp->addr); + scsi_u64to8b(volume_size - 1, srp->addr); scsi_ulto4b(sector_size, srp->length); ctio->dxfer_len = sizeof(*srp); @@ -416,6 +463,7 @@ tcmd_rd_cap(struct ccb_accept_tio *atio, struct ccb_scsiio *ctio) ctio->scsi_status = SCSI_STATUS_OK; return (0); } +#endif static int tcmd_rdwr(struct ccb_accept_tio *atio, struct ccb_scsiio *ctio) @@ -443,13 +491,21 @@ 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) - warnx("Starting DIR_IN @%lld:%u", c_descr->offset, - a_descr->targ_req); +#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); } else { ret = start_io(atio, ctio, CAM_DIR_OUT); if (debug) - warnx("Starting DIR_OUT @%lld:%u", c_descr->offset, - a_descr->init_req); +#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); } return (ret); @@ -458,7 +514,8 @@ tcmd_rdwr(struct ccb_accept_tio *atio, struct ccb_scsiio *ctio) static int tcmd_rdwr_decode(struct ccb_accept_tio *atio, struct ccb_scsiio *ctio) { - u_int32_t blkno, count; + uint64_t blkno; + uint32_t count; struct atio_descr *a_descr; u_int8_t *cdb; @@ -467,14 +524,36 @@ tcmd_rdwr_decode(struct ccb_accept_tio *atio, struct ccb_scsiio *ctio) if (debug) cdb_debug(cdb, "R/W from %u: ", atio->init_id); - if (cdb[0] == READ_6 || cdb[0] == WRITE_6) { + switch (cdb[0]) { + case READ_6: + case WRITE_6: + { struct scsi_rw_6 *rw_6 = (struct scsi_rw_6 *)cdb; blkno = scsi_3btoul(rw_6->addr); count = rw_6->length; - } else { + break; + } + case READ_10: + case WRITE_10: + { struct scsi_rw_10 *rw_10 = (struct scsi_rw_10 *)cdb; blkno = scsi_4btoul(rw_10->addr); count = scsi_2btoul(rw_10->length); + break; + } +#ifdef READ_16 + case READ_16: + case WRITE_16: + { + struct scsi_rw_16 *rw_16 = (struct scsi_rw_16 *)cdb; + blkno = scsi_8btou64(rw_16->addr); + count = scsi_4btoul(rw_16->length); + break; + } +#endif + default: + tcmd_illegal_req(atio, ctio); + return (0); } if (blkno + count > volume_size) { warnx("Attempt to access past end of volume"); @@ -488,17 +567,29 @@ 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) - warnx("r/w 0 blocks @ blkno %u", blkno); +#if __FreeBSD_version >= 500000 + warnx("r/w 0 blocks @ blkno %ju", blkno); +#else + warnx("r/w 0 blocks @ blkno %llu", blkno); +#endif 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) - warnx("write %u blocks @ blkno %u", count, blkno); +#if __FreeBSD_version >= 500000 + warnx("write %u blocks @ blkno %ju", count, blkno); +#else + warnx("write %u blocks @ blkno %llu", count, blkno); +#endif } else { a_descr->flags |= CAM_DIR_IN; if (debug) - warnx("read %u blocks @ blkno %u", count, blkno); +#if __FreeBSD_version >= 500000 + warnx("read %u blocks @ blkno %ju", count, blkno); +#else + warnx("read %u blocks @ blkno %llu", count, blkno); +#endif } return (1); } diff --git a/share/examples/scsi_target/scsi_target.8 b/share/examples/scsi_target/scsi_target.8 index cb5698d01656..798358100d27 100644 --- a/share/examples/scsi_target/scsi_target.8 +++ b/share/examples/scsi_target/scsi_target.8 @@ -94,6 +94,17 @@ and its associated control device. Use a different size for the emulated volume. Must be less than or equal to the size of .Ar filename . +If the number ends with a +.Dq Li k , +.Dq Li m , +.Dq Li g , +.Dq Li t , +.Dq Li p , +or +.Dq Li e , +the number is multiplied by 2^10 (1K), 2^20 (1M), 2^30 (1G), 2^40 (1T), +2^50 (1P) and 2^60 (1E) +respectively. .El .Pp Required arguments: diff --git a/share/examples/scsi_target/scsi_target.c b/share/examples/scsi_target/scsi_target.c index d1bcb272e8ec..ef4fd976c85f 100644 --- a/share/examples/scsi_target/scsi_target.c +++ b/share/examples/scsi_target/scsi_target.c @@ -29,6 +29,7 @@ */ #include <sys/types.h> +#include <ctype.h> #include <errno.h> #include <err.h> #include <fcntl.h> @@ -61,8 +62,8 @@ /* Global variables */ int debug; -u_int32_t volume_size; -size_t sector_size; +off_t volume_size; +u_int sector_size; size_t buf_size; /* Local variables */ @@ -141,10 +142,39 @@ main(int argc, char *argv[]) errx(1, "Unreasonable sector size: %s", optarg); break; case 's': + { + int last, shift = 0; + + last = strlen(optarg) - 1; + if (last > 0) { + switch (tolower(optarg[last])) { + case 'e': + shift += 10; + /* FALLTHROUGH */ + case 'p': + shift += 10; + /* FALLTHROUGH */ + case 't': + shift += 10; + /* FALLTHROUGH */ + case 'g': + shift += 10; + /* FALLTHROUGH */ + case 'm': + shift += 10; + /* FALLTHROUGH */ + case 'k': + shift += 10; + optarg[last] = 0; + break; + } + } user_size = strtoll(optarg, (char **)NULL, /*base*/10); + user_size <<= shift; if (user_size < 0) errx(1, "Unreasonable volume size: %s", optarg); break; + } case 'W': req_flags &= ~(SID_WBus16 | SID_WBus32); switch (atoi(optarg)) { @@ -215,6 +245,14 @@ main(int argc, char *argv[]) } else { volume_size = user_size / sector_size; } + if (debug) +#if __FreeBSD_version >= 500000 + warnx("volume_size: %d bytes x %jd sectors", +#else + warnx("volume_size: %d bytes x %lld sectors", +#endif + sector_size, volume_size); + if (volume_size <= 0) errx(1, "volume must be larger than %d", sector_size); diff --git a/share/examples/scsi_target/scsi_target.h b/share/examples/scsi_target/scsi_target.h index 7e179ff256bc..4f7ad68687da 100644 --- a/share/examples/scsi_target/scsi_target.h +++ b/share/examples/scsi_target/scsi_target.h @@ -51,11 +51,11 @@ TAILQ_HEAD(io_queue, ccb_hdr); /* Descriptor attached to each ATIO */ struct atio_descr { off_t base_off; /* Base offset for ATIO */ - size_t total_len; /* Total xfer len for this ATIO */ - size_t init_req; /* Transfer count requested to/from init */ - size_t init_ack; /* Data transferred ok to/from init */ - size_t targ_req; /* Transfer count requested to/from target */ - size_t targ_ack; /* Data transferred ok to/from target */ + uint total_len; /* Total xfer len for this ATIO */ + uint init_req; /* Transfer count requested to/from init */ + uint init_ack; /* Data transferred ok to/from init */ + uint targ_req; /* Transfer count requested to/from target */ + uint targ_ack; /* Data transferred ok to/from target */ int flags; /* Flags for CTIOs */ u_int8_t *cdb; /* Pointer to received CDB */ /* List of completed AIO/CTIOs */ |