aboutsummaryrefslogtreecommitdiff
path: root/sys/cam/ctl
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2020-08-06 19:16:11 +0000
committerAlexander Motin <mav@FreeBSD.org>2020-08-06 19:16:11 +0000
commit8bdf81e4d14d9b31cd0a7931de59510c3a6761c2 (patch)
treed42a42d4b991cb7ed55660f2332d3312f427342b /sys/cam/ctl
parente039e3d1d2075c7f5ad596e6c7a3453775b691d0 (diff)
downloadsrc-8bdf81e4d14d9b31cd0a7931de59510c3a6761c2.tar.gz
src-8bdf81e4d14d9b31cd0a7931de59510c3a6761c2.zip
Add CTL support for REPORT IDENTIFYING INFORMATION command.
It allows to report to initiator LU identifying information, preset via "ident_info" and "text_ident_info" options. Unfortunately it is impossible to implement SET IDENTIFYING INFORMATION, since we have no persistent storage it requires, so the information is read-only for initiator and has to be set out-of-band. MFC after: 1 week Sponsored by: iXsystems, Inc.
Notes
Notes: svn path=/head/; revision=363979
Diffstat (limited to 'sys/cam/ctl')
-rw-r--r--sys/cam/ctl/ctl.c82
-rw-r--r--sys/cam/ctl/ctl_cmd_table.c20
-rw-r--r--sys/cam/ctl/ctl_private.h1
3 files changed, 98 insertions, 5 deletions
diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c
index 3c325a8242a8..0a09cc0b2c80 100644
--- a/sys/cam/ctl/ctl.c
+++ b/sys/cam/ctl/ctl.c
@@ -7130,6 +7130,88 @@ ctl_read_defect(struct ctl_scsiio *ctsio)
}
int
+ctl_report_ident_info(struct ctl_scsiio *ctsio)
+{
+ struct ctl_lun *lun = CTL_LUN(ctsio);
+ struct scsi_report_ident_info *cdb;
+ struct scsi_report_ident_info_data *rii_ptr;
+ struct scsi_report_ident_info_descr *riid_ptr;
+ const char *oii, *otii;
+ int retval, alloc_len, total_len = 0, len = 0;
+
+ CTL_DEBUG_PRINT(("ctl_report_ident_info\n"));
+
+ cdb = (struct scsi_report_ident_info *)ctsio->cdb;
+ retval = CTL_RETVAL_COMPLETE;
+
+ total_len = sizeof(struct scsi_report_ident_info_data);
+ switch (cdb->type) {
+ case RII_LUII:
+ oii = dnvlist_get_string(lun->be_lun->options,
+ "ident_info", NULL);
+ if (oii)
+ len = strlen(oii); /* Approximately */
+ break;
+ case RII_LUTII:
+ otii = dnvlist_get_string(lun->be_lun->options,
+ "text_ident_info", NULL);
+ if (otii)
+ len = strlen(otii) + 1; /* NULL-terminated */
+ break;
+ case RII_IIS:
+ len = 2 * sizeof(struct scsi_report_ident_info_descr);
+ break;
+ default:
+ ctl_set_invalid_field(/*ctsio*/ ctsio,
+ /*sks_valid*/ 1,
+ /*command*/ 1,
+ /*field*/ 11,
+ /*bit_valid*/ 1,
+ /*bit*/ 2);
+ ctl_done((union ctl_io *)ctsio);
+ return(retval);
+ }
+ total_len += len;
+ alloc_len = scsi_4btoul(cdb->length);
+
+ ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO);
+ ctsio->kern_sg_entries = 0;
+ ctsio->kern_rel_offset = 0;
+ ctsio->kern_data_len = min(total_len, alloc_len);
+ ctsio->kern_total_len = ctsio->kern_data_len;
+
+ rii_ptr = (struct scsi_report_ident_info_data *)ctsio->kern_data_ptr;
+ switch (cdb->type) {
+ case RII_LUII:
+ if (oii) {
+ if (oii[0] == '0' && oii[1] == 'x')
+ len = hex2bin(oii, (uint8_t *)(rii_ptr + 1), len);
+ else
+ strncpy((uint8_t *)(rii_ptr + 1), oii, len);
+ }
+ break;
+ case RII_LUTII:
+ if (otii)
+ strlcpy((uint8_t *)(rii_ptr + 1), otii, len);
+ break;
+ case RII_IIS:
+ riid_ptr = (struct scsi_report_ident_info_descr *)(rii_ptr + 1);
+ riid_ptr->type = RII_LUII;
+ scsi_ulto2b(0xffff, riid_ptr->length);
+ riid_ptr++;
+ riid_ptr->type = RII_LUTII;
+ scsi_ulto2b(0xffff, riid_ptr->length);
+ }
+ scsi_ulto2b(len, rii_ptr->length);
+
+ ctl_set_success(ctsio);
+ 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_report_tagret_port_groups(struct ctl_scsiio *ctsio)
{
struct ctl_softc *softc = CTL_SOFTC(ctsio);
diff --git a/sys/cam/ctl/ctl_cmd_table.c b/sys/cam/ctl/ctl_cmd_table.c
index ffe02824975b..b3780dcf8c67 100644
--- a/sys/cam/ctl/ctl_cmd_table.c
+++ b/sys/cam/ctl/ctl_cmd_table.c
@@ -829,8 +829,15 @@ const struct ctl_cmd_entry ctl_cmd_table_a3[32] =
/* 04 */
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
-/* 05 */
-{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
+/* 05 REPORT IDENTIFYING INFORMATION */
+{ctl_report_ident_info, CTL_SERIDX_INQ, CTL_CMD_FLAG_OK_ON_BOTH |
+ CTL_CMD_FLAG_OK_ON_NO_MEDIA |
+ CTL_CMD_FLAG_OK_ON_STANDBY |
+ CTL_CMD_FLAG_OK_ON_UNAVAIL |
+ CTL_FLAG_DATA_IN |
+ CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
+ CTL_LUN_PAT_NONE,
+ 12, {0x0f, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x07}},
/* 06 */
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
@@ -854,7 +861,7 @@ const struct ctl_cmd_entry ctl_cmd_table_a3[32] =
CTL_LUN_PAT_NONE,
12, {0xea, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
-/* 0B */
+/* 0B REPORT ALIASES */
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
/* 0C REPORT SUPPORTED_OPCODES */
@@ -877,7 +884,7 @@ const struct ctl_cmd_entry ctl_cmd_table_a3[32] =
CTL_LUN_PAT_NONE,
12, {0x0d, 0x80, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
-/* 0E */
+/* 0E REPORT PRIORITY */
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
/* 0F REPORT TIMESTAMP */
@@ -890,7 +897,10 @@ const struct ctl_cmd_entry ctl_cmd_table_a3[32] =
CTL_LUN_PAT_NONE,
12, {0x0f, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
-/* 10-1f */
+/* 10 MANAGEMENT PROTOCOL IN */
+{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
+
+/* 11-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 5dd82d3032ac..cf67deb13ef7 100644
--- a/sys/cam/ctl/ctl_private.h
+++ b/sys/cam/ctl/ctl_private.h
@@ -517,6 +517,7 @@ int ctl_get_event_status(struct ctl_scsiio *ctsio);
int ctl_mechanism_status(struct ctl_scsiio *ctsio);
int ctl_persistent_reserve_in(struct ctl_scsiio *ctsio);
int ctl_persistent_reserve_out(struct ctl_scsiio *ctsio);
+int ctl_report_ident_info(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);