Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F106127394
D44722.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D44722.diff
View Options
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
@@ -578,7 +578,7 @@
}
static int
-ctl_backend_ramdisk_config_read(union ctl_io *io)
+ctl_backend_ramdisk_scsi_config_read(union ctl_io *io)
{
int retval = 0;
@@ -606,6 +606,89 @@
return (retval);
}
+static int
+ramdisk_namespace_data(union ctl_io *io)
+{
+ struct ctl_be_lun *cbe_lun = CTL_BACKEND_LUN(io);
+ struct ctl_be_ramdisk_lun *be_lun = (struct ctl_be_ramdisk_lun *)cbe_lun;
+ struct nvme_namespace_data *nsdata;
+
+ if (io->nvmeio.kern_data_len != sizeof(struct nvme_namespace_data) ||
+ io->nvmeio.kern_sg_entries != 0)
+ return (CTL_RETVAL_ERROR);
+
+ nsdata = (struct nvme_namespace_data *)io->nvmeio.kern_data_ptr;
+ memset(nsdata, 0, sizeof(*nsdata));
+ nsdata->nsze = htole64(be_lun->size_blocks);
+ nsdata->ncap = htole64(be_lun->cap_bytes / cbe_lun->blocksize);
+ nsdata->nuse = htole64(be_lun->cap_used / cbe_lun->blocksize);
+ nsdata->nsfeat = NVMEM(NVME_NS_DATA_NSFEAT_THIN_PROV) |
+ NVMEM(NVME_NS_DATA_NSFEAT_DEALLOC);
+ nsdata->nlbaf = 1 - 1;
+ nsdata->dlfeat = NVMEM(NVME_NS_DATA_DLFEAT_DWZ) |
+ NVMEF(NVME_NS_DATA_DLFEAT_READ, NVME_NS_DATA_DLFEAT_READ_00);
+ nsdata->flbas = NVMEF(NVME_NS_DATA_FLBAS_FORMAT, 0);
+ nsdata->lbaf[0] = NVMEF(NVME_NS_DATA_LBAF_LBADS,
+ ffs(cbe_lun->blocksize) - 1);
+
+ ctl_lun_nsdata_ids(cbe_lun, nsdata);
+ ctl_config_read_done(io);
+ return (CTL_RETVAL_COMPLETE);
+}
+
+static int
+ramdisk_nvme_ids(union ctl_io *io)
+{
+ struct ctl_be_lun *cbe_lun = CTL_BACKEND_LUN(io);
+
+ if (io->nvmeio.kern_data_len != 4096 || io->nvmeio.kern_sg_entries != 0)
+ return (CTL_RETVAL_ERROR);
+
+ ctl_lun_nvme_ids(cbe_lun, io->nvmeio.kern_data_ptr);
+ ctl_config_read_done(io);
+ return (CTL_RETVAL_COMPLETE);
+}
+
+static int
+ctl_backend_ramdisk_nvme_config_read(union ctl_io *io)
+{
+ switch (io->nvmeio.cmd.opc) {
+ case NVME_OPC_IDENTIFY:
+ {
+ uint8_t cns;
+
+ cns = le32toh(io->nvmeio.cmd.cdw10) & 0xff;
+ switch (cns) {
+ case 0:
+ return (ramdisk_namespace_data(io));
+ case 3:
+ return (ramdisk_nvme_ids(io));
+ default:
+ ctl_nvme_set_invalid_field(&io->nvmeio);
+ ctl_config_read_done(io);
+ return (CTL_RETVAL_COMPLETE);
+ }
+ }
+ default:
+ ctl_nvme_set_invalid_opcode(&io->nvmeio);
+ ctl_config_read_done(io);
+ return (CTL_RETVAL_COMPLETE);
+ }
+}
+
+static int
+ctl_backend_ramdisk_config_read(union ctl_io *io)
+{
+ switch (io->io_hdr.io_type) {
+ case CTL_IO_SCSI:
+ return (ctl_backend_ramdisk_scsi_config_read(io));
+ case CTL_IO_NVME_ADMIN:
+ return (ctl_backend_ramdisk_nvme_config_read(io));
+ default:
+ __assert_unreachable();
+ }
+}
+
static void
ctl_backend_ramdisk_delete(struct ctl_be_lun *cbe_lun, off_t lba, off_t len,
int anchor)
@@ -658,6 +741,8 @@
uint64_t lba;
u_int lbaoff, lbas;
+ CTL_IO_ASSERT(io, SCSI);
+
if (lbalen->flags & ~(SWS_LBDATA | SWS_UNMAP | SWS_ANCHOR | SWS_NDOB)) {
ctl_set_invalid_field(&io->scsiio,
/*sks_valid*/ 1,
@@ -706,6 +791,8 @@
struct ctl_ptr_len_flags *ptrlen = (struct ctl_ptr_len_flags *)ARGS(io);
struct scsi_unmap_desc *buf, *end;
+ CTL_IO_ASSERT(io, SCSI);
+
if ((ptrlen->flags & ~SU_ANCHOR) != 0) {
ctl_set_invalid_field(&io->scsiio,
/*sks_valid*/ 0,
@@ -730,7 +817,7 @@
}
static int
-ctl_backend_ramdisk_config_write(union ctl_io *io)
+ctl_backend_ramdisk_scsi_config_write(union ctl_io *io)
{
struct ctl_be_lun *cbe_lun = CTL_BACKEND_LUN(io);
int retval = 0;
@@ -785,6 +872,122 @@
return (retval);
}
+static void
+ctl_backend_ramdisk_wu(union ctl_io *io)
+{
+ struct ctl_be_lun *cbe_lun = CTL_BACKEND_LUN(io);
+ struct ctl_lba_len_flags *lbalen = ARGS(io);
+
+ CTL_IO_ASSERT(io, NVME);
+
+ /*
+ * XXX: Not quite right as reads will return zeroes rather
+ * than failing.
+ */
+ ctl_backend_ramdisk_delete(cbe_lun, lbalen->lba, lbalen->len, 1);
+ ctl_nvme_set_success(&io->nvmeio);
+ ctl_config_write_done(io);
+}
+
+static void
+ctl_backend_ramdisk_wz(union ctl_io *io)
+{
+ struct ctl_be_lun *cbe_lun = CTL_BACKEND_LUN(io);
+ struct ctl_be_ramdisk_lun *be_lun = (struct ctl_be_ramdisk_lun *)cbe_lun;
+ struct ctl_lba_len_flags *lbalen = ARGS(io);
+ uint8_t *page;
+ uint64_t lba;
+ u_int lbaoff, lbas;
+
+ CTL_IO_ASSERT(io, NVME);
+
+ if ((le32toh(io->nvmeio.cmd.cdw12) & (1U << 25)) != 0) {
+ ctl_backend_ramdisk_delete(cbe_lun, lbalen->lba, lbalen->len,
+ 0);
+ ctl_nvme_set_success(&io->nvmeio);
+ ctl_config_write_done(io);
+ return;
+ }
+
+ for (lba = lbalen->lba, lbas = lbalen->len; lbas > 0; lba++, lbas--) {
+ page = ctl_backend_ramdisk_getpage(be_lun,
+ lba >> cbe_lun->pblockexp, GP_WRITE);
+ if (page == P_UNMAPPED || page == P_ANCHORED) {
+ ctl_nvme_set_space_alloc_fail(&io->nvmeio);
+ ctl_data_submit_done(io);
+ return;
+ }
+ lbaoff = lba & ~(UINT_MAX << cbe_lun->pblockexp);
+ page += lbaoff * cbe_lun->blocksize;
+ memset(page, 0, cbe_lun->blocksize);
+ }
+ ctl_nvme_set_success(&io->nvmeio);
+ ctl_config_write_done(io);
+}
+
+static void
+ctl_backend_ramdisk_dsm(union ctl_io *io)
+{
+ struct ctl_be_lun *cbe_lun = CTL_BACKEND_LUN(io);
+ struct nvme_dsm_range *r;
+ uint64_t lba;
+ uint32_t num_blocks;
+ u_int i, ranges;
+
+ CTL_IO_ASSERT(io, NVME);
+
+ ranges = le32toh(io->nvmeio.cmd.cdw10) & 0xff;
+ r = (struct nvme_dsm_range *)io->nvmeio.kern_data_ptr;
+ for (i = 0; i < ranges; i++) {
+ lba = le64toh(r[i].starting_lba);
+ num_blocks = le32toh(r[i].length);
+ if ((le32toh(r[i].attributes) & (1U << 2)) != 0)
+ ctl_backend_ramdisk_delete(cbe_lun, lba, num_blocks, 0);
+ }
+
+ ctl_nvme_set_success(&io->nvmeio);
+ ctl_config_write_done(io);
+}
+
+static int
+ctl_backend_ramdisk_nvme_config_write(union ctl_io *io)
+{
+ switch (io->nvmeio.cmd.opc) {
+ case NVME_OPC_FLUSH:
+ /* We have no cache to flush. */
+ ctl_nvme_set_success(&io->nvmeio);
+ ctl_config_write_done(io);
+ break;
+ case NVME_OPC_WRITE_UNCORRECTABLE:
+ ctl_backend_ramdisk_wu(io);
+ break;
+ case NVME_OPC_WRITE_ZEROES:
+ ctl_backend_ramdisk_wz(io);
+ break;
+ case NVME_OPC_DATASET_MANAGEMENT:
+ ctl_backend_ramdisk_dsm(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)
+{
+ switch (io->io_hdr.io_type) {
+ case CTL_IO_SCSI:
+ return (ctl_backend_ramdisk_scsi_config_write(io));
+ case CTL_IO_NVME:
+ return (ctl_backend_ramdisk_nvme_config_write(io));
+ default:
+ __assert_unreachable();
+ }
+}
+
static uint64_t
ctl_backend_ramdisk_lun_attr(struct ctl_be_lun *cbe_lun, const char *attrname)
{
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Dec 26, 8:41 PM (11 h, 22 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15607764
Default Alt Text
D44722.diff (6 KB)
Attached To
Mode
D44722: ctl_backend_ramdisk: Add support for NVMe
Attached
Detach File
Event Timeline
Log In to Comment