Page MenuHomeFreeBSD

D61562.1794767630.diff
No OneTemporary

Authored By
Unknown
Size
5 KB
Referenced Files
None
Subscribers
None

D61562.1794767630.diff

diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c
--- a/sys/cam/ctl/ctl.c
+++ b/sys/cam/ctl/ctl.c
@@ -10793,6 +10793,36 @@
return (retval);
}
+int
+ctl_nvme_set_features(struct ctl_nvmeio *ctnio)
+{
+ struct ctl_lun *lun = CTL_LUN(ctnio);
+ int retval;
+
+ CTL_DEBUG_PRINT(("ctl_nvme_set_features\n"));
+
+ CTL_IO_ASSERT(ctnio, NVME_ADMIN);
+ MPASS(ctnio->cmd.opc == NVME_OPC_SET_FEATURES);
+
+ retval = lun->backend->config_write((union ctl_io *)ctnio);
+ return (retval);
+}
+
+int
+ctl_nvme_get_features(struct ctl_nvmeio *ctnio)
+{
+ struct ctl_lun *lun = CTL_LUN(ctnio);
+ int retval;
+
+ CTL_DEBUG_PRINT(("ctl_nvme_get_features\n"));
+
+ CTL_IO_ASSERT(ctnio, NVME_ADMIN);
+ MPASS(ctnio->cmd.opc == NVME_OPC_GET_FEATURES);
+
+ retval = lun->backend->config_read((union ctl_io *)ctnio);
+ return (retval);
+}
+
int
ctl_nvme_flush(struct ctl_nvmeio *ctnio)
{
diff --git a/sys/cam/ctl/ctl_backend_block.c b/sys/cam/ctl/ctl_backend_block.c
--- a/sys/cam/ctl/ctl_backend_block.c
+++ b/sys/cam/ctl/ctl_backend_block.c
@@ -3143,6 +3143,47 @@
return (CTL_RETVAL_COMPLETE);
}
+static int
+ctl_be_block_nvme_admin_config_write(union ctl_io *io)
+{
+ DPRINTF("entered\n");
+
+ switch (io->nvmeio.cmd.opc) {
+ case NVME_OPC_SET_FEATURES:
+ {
+ uint8_t fid;
+
+ fid = NVMEV(NVME_FEAT_GET_FID, le32toh(io->nvmeio.cmd.cdw10));
+ switch (fid) {
+ case NVME_FEAT_ERROR_RECOVERY:
+ {
+ uint32_t val;
+
+ val = le32toh(io->nvmeio.cmd.cdw11);
+ if ((val & 0xffffff00) != 0) {
+ ctl_nvme_set_invalid_field(&io->nvmeio);
+ break;
+ }
+
+ /* Ignore any timeout set for TLER. */
+ ctl_nvme_set_success(&io->nvmeio);
+ break;
+ }
+ default:
+ ctl_nvme_set_invalid_field(&io->nvmeio);
+ break;
+ }
+ ctl_config_write_done(io);
+ break;
+ }
+ default:
+ ctl_nvme_set_invalid_opcode(&io->nvmeio);
+ ctl_config_write_done(io);
+ break;
+ }
+ return (CTL_RETVAL_COMPLETE);
+}
+
static int
ctl_be_block_config_write(union ctl_io *io)
{
@@ -3151,6 +3192,8 @@
return (ctl_be_block_scsi_config_write(io));
case CTL_IO_NVME:
return (ctl_be_block_nvme_config_write(io));
+ case CTL_IO_NVME_ADMIN:
+ return (ctl_be_block_nvme_admin_config_write(io));
default:
__assert_unreachable();
}
@@ -3229,6 +3272,24 @@
}
break;
}
+ case NVME_OPC_GET_FEATURES:
+ {
+ uint8_t fid;
+
+ fid = NVMEV(NVME_FEAT_GET_FID, le32toh(io->nvmeio.cmd.cdw10));
+ switch (fid) {
+ case NVME_FEAT_ERROR_RECOVERY:
+ /* Always report no timeout for TLER. */
+ ctl_nvme_set_success(&io->nvmeio);
+ io->nvmeio.cpl.cdw0 = htole32(0);
+ break;
+ default:
+ ctl_nvme_set_invalid_field(&io->nvmeio);
+ break;
+ }
+ ctl_config_read_done(io);
+ break;
+ }
default:
ctl_nvme_set_invalid_opcode(&io->nvmeio);
ctl_config_read_done(io);
diff --git a/sys/cam/ctl/ctl_backend_ramdisk.c b/sys/cam/ctl/ctl_backend_ramdisk.c
--- a/sys/cam/ctl/ctl_backend_ramdisk.c
+++ b/sys/cam/ctl/ctl_backend_ramdisk.c
@@ -668,6 +668,25 @@
return (CTL_RETVAL_COMPLETE);
}
}
+ case NVME_OPC_GET_FEATURES:
+ {
+ uint8_t fid;
+
+ fid = NVMEV(NVME_FEAT_GET_FID, le32toh(io->nvmeio.cmd.cdw10));
+ switch (fid) {
+ case NVME_FEAT_ERROR_RECOVERY:
+ /* Always report no timeout for TLER. */
+ ctl_nvme_set_success(&io->nvmeio);
+ io->nvmeio.cpl.cdw0 = htole32(0);
+ ctl_config_read_done(io);
+ return (CTL_RETVAL_COMPLETE);
+ default:
+ ctl_nvme_set_invalid_field(&io->nvmeio);
+ ctl_config_read_done(io);
+ return (CTL_RETVAL_COMPLETE);
+ }
+ break;
+ }
default:
ctl_nvme_set_invalid_opcode(&io->nvmeio);
ctl_config_read_done(io);
@@ -974,6 +993,45 @@
return (CTL_RETVAL_COMPLETE);
}
+static int
+ctl_backend_ramdisk_nvme_admin_config_write(union ctl_io *io)
+{
+ switch (io->nvmeio.cmd.opc) {
+ case NVME_OPC_SET_FEATURES:
+ {
+ uint8_t fid;
+
+ fid = NVMEV(NVME_FEAT_GET_FID, le32toh(io->nvmeio.cmd.cdw10));
+ switch (fid) {
+ case NVME_FEAT_ERROR_RECOVERY:
+ {
+ uint32_t val;
+
+ val = le32toh(io->nvmeio.cmd.cdw11);
+ if ((val & 0xffffff00) != 0) {
+ ctl_nvme_set_invalid_field(&io->nvmeio);
+ break;
+ }
+
+ /* Ignore any timeout set for TLER. */
+ ctl_nvme_set_success(&io->nvmeio);
+ break;
+ }
+ default:
+ ctl_nvme_set_invalid_field(&io->nvmeio);
+ break;
+ }
+ ctl_config_write_done(io);
+ break;
+ }
+ default:
+ ctl_nvme_set_invalid_opcode(&io->nvmeio);
+ ctl_config_write_done(io);
+ break;
+ }
+ return (CTL_RETVAL_COMPLETE);
+}
+
static int
ctl_backend_ramdisk_config_write(union ctl_io *io)
{
@@ -982,6 +1040,8 @@
return (ctl_backend_ramdisk_scsi_config_write(io));
case CTL_IO_NVME:
return (ctl_backend_ramdisk_nvme_config_write(io));
+ case CTL_IO_NVME_ADMIN:
+ return (ctl_backend_ramdisk_nvme_admin_config_write(io));
default:
__assert_unreachable();
}
diff --git a/sys/cam/ctl/ctl_nvme_cmd_table.c b/sys/cam/ctl/ctl_nvme_cmd_table.c
--- a/sys/cam/ctl/ctl_nvme_cmd_table.c
+++ b/sys/cam/ctl/ctl_nvme_cmd_table.c
@@ -17,6 +17,8 @@
{
[NVME_OPC_IDENTIFY] = { ctl_nvme_identify, CTL_FLAG_DATA_IN |
CTL_CMD_FLAG_OK_ON_NO_LUN },
+ [NVME_OPC_SET_FEATURES] = { ctl_nvme_set_features, CTL_FLAG_DATA_NONE },
+ [NVME_OPC_GET_FEATURES] = { ctl_nvme_get_features, CTL_FLAG_DATA_NONE },
};
/* NVM Command Set (CTL_IO_NVME). */
diff --git a/sys/cam/ctl/ctl_private.h b/sys/cam/ctl/ctl_private.h
--- a/sys/cam/ctl/ctl_private.h
+++ b/sys/cam/ctl/ctl_private.h
@@ -478,6 +478,8 @@
int ctl_get_lba_status(struct ctl_scsiio *ctsio);
int ctl_nvme_identify(struct ctl_nvmeio *ctnio);
+int ctl_nvme_set_features(struct ctl_nvmeio *ctnio);
+int ctl_nvme_get_features(struct ctl_nvmeio *ctnio);
int ctl_nvme_flush(struct ctl_nvmeio *ctnio);
int ctl_nvme_read_write(struct ctl_nvmeio *ctnio);
int ctl_nvme_write_uncorrectable(struct ctl_nvmeio *ctnio);

File Metadata

Mime Type
text/plain
Expires
Sun, Nov 15, 6:33 PM (22 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41746788
Default Alt Text
D61562.1794767630.diff (5 KB)

Event Timeline