summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2014-07-15 16:54:04 +0000
committermav <mav@FreeBSD.org>2014-07-15 16:54:04 +0000
commit75f2a987710660a3c2af6958891e45f24decd6db (patch)
treeb1a2c8496f90e75166d52bf9b0bdfeea47e0f414
parentda977d403200a33558605a0f258a3e6077c11715 (diff)
downloadFreeBSD-src-75f2a987710660a3c2af6958891e45f24decd6db.zip
FreeBSD-src-75f2a987710660a3c2af6958891e45f24decd6db.tar.gz
MFC r268103:
Add support for REPORT TIMESTAMP command.
-rw-r--r--sys/cam/ctl/ctl.c52
-rw-r--r--sys/cam/ctl/ctl_cmd_table.c14
-rw-r--r--sys/cam/ctl/ctl_private.h1
-rw-r--r--sys/cam/scsi/scsi_all.h23
4 files changed, 89 insertions, 1 deletions
diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c
index c00d908..f785908 100644
--- a/sys/cam/ctl/ctl.c
+++ b/sys/cam/ctl/ctl.c
@@ -7292,6 +7292,58 @@ ctl_report_supported_tmf(struct ctl_scsiio *ctsio)
}
int
+ctl_report_timestamp(struct ctl_scsiio *ctsio)
+{
+ struct ctl_lun *lun;
+ struct scsi_report_timestamp *cdb;
+ struct scsi_report_timestamp_data *data;
+ struct timeval tv;
+ int64_t timestamp;
+ int retval;
+ int alloc_len, total_len;
+
+ CTL_DEBUG_PRINT(("ctl_report_timestamp\n"));
+
+ cdb = (struct scsi_report_timestamp *)ctsio->cdb;
+ lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
+
+ retval = CTL_RETVAL_COMPLETE;
+
+ total_len = sizeof(struct scsi_report_timestamp_data);
+ alloc_len = scsi_4btoul(cdb->length);
+
+ ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO);
+
+ ctsio->kern_sg_entries = 0;
+
+ if (total_len < alloc_len) {
+ ctsio->residual = alloc_len - total_len;
+ ctsio->kern_data_len = total_len;
+ ctsio->kern_total_len = total_len;
+ } else {
+ ctsio->residual = 0;
+ ctsio->kern_data_len = alloc_len;
+ ctsio->kern_total_len = alloc_len;
+ }
+ ctsio->kern_data_resid = 0;
+ ctsio->kern_rel_offset = 0;
+
+ data = (struct scsi_report_timestamp_data *)ctsio->kern_data_ptr;
+ scsi_ulto2b(sizeof(*data) - 2, data->length);
+ data->origin = RTS_ORIG_OUTSIDE;
+ getmicrotime(&tv);
+ timestamp = (int64_t)tv.tv_sec * 1000 + tv.tv_usec / 1000;
+ scsi_ulto4b(timestamp >> 16, data->timestamp);
+ scsi_ulto2b(timestamp & 0xffff, &data->timestamp[4]);
+
+ ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED;
+ ctsio->be_move_done = ctl_config_move_done;
+
+ ctl_datamove((union ctl_io *)ctsio);
+ return (retval);
+}
+
+int
ctl_persistent_reserve_in(struct ctl_scsiio *ctsio)
{
struct scsi_per_res_in *cdb;
diff --git a/sys/cam/ctl/ctl_cmd_table.c b/sys/cam/ctl/ctl_cmd_table.c
index 7187d3d..46f2999 100644
--- a/sys/cam/ctl/ctl_cmd_table.c
+++ b/sys/cam/ctl/ctl_cmd_table.c
@@ -309,7 +309,19 @@ const struct ctl_cmd_entry ctl_cmd_table_a3[32] =
CTL_LUN_PAT_NONE,
12, {0x0d, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
-/* 0e-1f */
+/* 0E */
+{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
+
+/* 0F REPORT TIMESTAMP */
+{ctl_report_timestamp, CTL_SERIDX_MAIN_IN, CTL_CMD_FLAG_OK_ON_BOTH |
+ CTL_CMD_FLAG_OK_ON_STOPPED |
+ CTL_CMD_FLAG_OK_ON_INOPERABLE |
+ CTL_CMD_FLAG_OK_ON_SECONDARY |
+ CTL_FLAG_DATA_IN,
+ CTL_LUN_PAT_NONE,
+ 12, {0x0f, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
+
+/* 10-1f */
};
const struct ctl_cmd_entry ctl_cmd_table[256] =
diff --git a/sys/cam/ctl/ctl_private.h b/sys/cam/ctl/ctl_private.h
index 1c9b7d9..570826c 100644
--- a/sys/cam/ctl/ctl_private.h
+++ b/sys/cam/ctl/ctl_private.h
@@ -501,6 +501,7 @@ int ctl_persistent_reserve_out(struct ctl_scsiio *ctsio);
int ctl_report_tagret_port_groups(struct ctl_scsiio *ctsio);
int ctl_report_supported_opcodes(struct ctl_scsiio *ctsio);
int ctl_report_supported_tmf(struct ctl_scsiio *ctsio);
+int ctl_report_timestamp(struct ctl_scsiio *ctsio);
int ctl_isc(struct ctl_scsiio *ctsio);
#endif /* _KERNEL */
diff --git a/sys/cam/scsi/scsi_all.h b/sys/cam/scsi/scsi_all.h
index 545f493..52c04f5 100644
--- a/sys/cam/scsi/scsi_all.h
+++ b/sys/cam/scsi/scsi_all.h
@@ -1059,6 +1059,29 @@ struct scsi_report_supported_tmf_data
uint8_t reserved[2];
};
+struct scsi_report_timestamp
+{
+ uint8_t opcode;
+ uint8_t service_action;
+ uint8_t reserved[4];
+ uint8_t length[4];
+ uint8_t reserved1;
+ uint8_t control;
+};
+
+struct scsi_report_timestamp_data
+{
+ uint8_t length[2];
+ uint8_t origin;
+#define RTS_ORIG_MASK 0x00
+#define RTS_ORIG_ZERO 0x00
+#define RTS_ORIG_SET 0x02
+#define RTS_ORIG_OUTSIDE 0x03
+ uint8_t reserved;
+ uint8_t timestamp[6];
+ uint8_t reserve2[2];
+};
+
struct ata_pass_16 {
u_int8_t opcode;
u_int8_t protocol;
OpenPOWER on IntegriCloud