diff options
author | mav <mav@FreeBSD.org> | 2014-07-15 16:54:04 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2014-07-15 16:54:04 +0000 |
commit | 75f2a987710660a3c2af6958891e45f24decd6db (patch) | |
tree | b1a2c8496f90e75166d52bf9b0bdfeea47e0f414 | |
parent | da977d403200a33558605a0f258a3e6077c11715 (diff) | |
download | FreeBSD-src-75f2a987710660a3c2af6958891e45f24decd6db.zip FreeBSD-src-75f2a987710660a3c2af6958891e45f24decd6db.tar.gz |
MFC r268103:
Add support for REPORT TIMESTAMP command.
-rw-r--r-- | sys/cam/ctl/ctl.c | 52 | ||||
-rw-r--r-- | sys/cam/ctl/ctl_cmd_table.c | 14 | ||||
-rw-r--r-- | sys/cam/ctl/ctl_private.h | 1 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_all.h | 23 |
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; |