summaryrefslogtreecommitdiffstats
path: root/share/examples
diff options
context:
space:
mode:
authorsimokawa <simokawa@FreeBSD.org>2003-10-18 04:54:08 +0000
committersimokawa <simokawa@FreeBSD.org>2003-10-18 04:54:08 +0000
commit40e3b17753e710000d21b27bd62ebb24488b54e8 (patch)
tree7dfef19d5a11887c9625cdc237ce0b3e9547bff4 /share/examples
parent9be7eda223c2ac639f4a2ce991a322b397fb0e3f (diff)
downloadFreeBSD-src-40e3b17753e710000d21b27bd62ebb24488b54e8.zip
FreeBSD-src-40e3b17753e710000d21b27bd62ebb24488b54e8.tar.gz
- Enable 16byte commands.
- Fix printf warnings on 64bit architectures. - Accept 'k', 'm' and etc. for -s option. Reviewed by: njl
Diffstat (limited to 'share/examples')
-rw-r--r--share/examples/scsi_target/scsi_cmds.c115
-rw-r--r--share/examples/scsi_target/scsi_target.811
-rw-r--r--share/examples/scsi_target/scsi_target.c42
-rw-r--r--share/examples/scsi_target/scsi_target.h10
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 331578f..efdb35e 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 cb5698d..7983581 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 d1bcb27..ef4fd97 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 7e179ff..4f7ad68 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 */
OpenPOWER on IntegriCloud