Commit 5fd075cd authored by Keith Busch's avatar Keith Busch
Browse files

nvmet: implement rotational media information log



Most of the information is stubbed. Supporting these commands is a
requirement for supporting rotational media.

Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarKeith Busch <kbusch@kernel.org>
parent 266b652c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -5002,6 +5002,7 @@ static inline void _nvme_check_size(void)
	BUILD_BUG_ON(sizeof(struct nvme_lba_range_type) != 64);
	BUILD_BUG_ON(sizeof(struct nvme_smart_log) != 512);
	BUILD_BUG_ON(sizeof(struct nvme_endurance_group_log) != 512);
	BUILD_BUG_ON(sizeof(struct nvme_rotational_media_log) != 512);
	BUILD_BUG_ON(sizeof(struct nvme_dbbuf) != 64);
	BUILD_BUG_ON(sizeof(struct nvme_directive_cmd) != 64);
	BUILD_BUG_ON(sizeof(struct nvme_feat_host_behavior) != 512);
+42 −0
Original line number Diff line number Diff line
@@ -91,6 +91,7 @@ static void nvmet_execute_get_supported_log_pages(struct nvmet_req *req)
	logs->lids[NVME_LOG_ENDURANCE_GROUP] = cpu_to_le32(NVME_LIDS_LSUPP);
	logs->lids[NVME_LOG_ANA] = cpu_to_le32(NVME_LIDS_LSUPP);
	logs->lids[NVME_LOG_FEATURES] = cpu_to_le32(NVME_LIDS_LSUPP);
	logs->lids[NVME_LOG_RMI] = cpu_to_le32(NVME_LIDS_LSUPP);
	logs->lids[NVME_LOG_RESERVATION] = cpu_to_le32(NVME_LIDS_LSUPP);

	status = nvmet_copy_to_sgl(req, 0, logs, sizeof(*logs));
@@ -158,6 +159,45 @@ static u16 nvmet_get_smart_log_all(struct nvmet_req *req,
	return NVME_SC_SUCCESS;
}

static void nvmet_execute_get_log_page_rmi(struct nvmet_req *req)
{
	struct nvme_rotational_media_log *log;
	struct gendisk *disk;
	u16 status;

	req->cmd->common.nsid = cpu_to_le32(le16_to_cpu(
					    req->cmd->get_log_page.lsi));
	status = nvmet_req_find_ns(req);
	if (status)
		goto out;

	if (!req->ns->bdev || bdev_nonrot(req->ns->bdev)) {
		status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR;
		goto out;
	}

	if (req->transfer_len != sizeof(*log)) {
		status = NVME_SC_SGL_INVALID_DATA | NVME_STATUS_DNR;
		goto out;
	}

	log = kzalloc(sizeof(*log), GFP_KERNEL);
	if (!log)
		goto out;

	log->endgid = req->cmd->get_log_page.lsi;
	disk = req->ns->bdev->bd_disk;
	if (disk && disk->ia_ranges)
		log->numa = cpu_to_le16(disk->ia_ranges->nr_ia_ranges);
	else
		log->numa = cpu_to_le16(1);

	status = nvmet_copy_to_sgl(req, 0, log, sizeof(*log));
	kfree(log);
out:
	nvmet_req_complete(req, status);
}

static void nvmet_execute_get_log_page_smart(struct nvmet_req *req)
{
	struct nvme_smart_log *log;
@@ -451,6 +491,8 @@ static void nvmet_execute_get_log_page(struct nvmet_req *req)
		return nvmet_execute_get_log_page_ana(req);
	case NVME_LOG_FEATURES:
		return nvmet_execute_get_log_page_features(req);
	case NVME_LOG_RMI:
		return nvmet_execute_get_log_page_rmi(req);
	case NVME_LOG_RESERVATION:
		return nvmet_execute_get_log_page_resv(req);
	}
+14 −1
Original line number Diff line number Diff line
@@ -642,6 +642,18 @@ struct nvme_endurance_group_log {
	__u8	rsvd192[320];
};

struct nvme_rotational_media_log {
	__le16	endgid;
	__le16	numa;
	__le16	nrs;
	__u8	rsvd6[2];
	__le32	spinc;
	__le32	fspinc;
	__le32	ldc;
	__le32	fldc;
	__u8	rsvd24[488];
};

struct nvme_smart_log {
	__u8			critical_warning;
	__u8			temperature[2];
@@ -1281,6 +1293,7 @@ enum {
	NVME_LOG_ENDURANCE_GROUP = 0x09,
	NVME_LOG_ANA		= 0x0c,
	NVME_LOG_FEATURES	= 0x12,
	NVME_LOG_RMI		= 0x16,
	NVME_LOG_DISC		= 0x70,
	NVME_LOG_RESERVATION	= 0x80,
	NVME_FWACT_REPL		= (0 << 3),
@@ -1435,7 +1448,7 @@ struct nvme_get_log_page_command {
	__u8			lsp; /* upper 4 bits reserved */
	__le16			numdl;
	__le16			numdu;
	__u16			rsvd11;
	__le16			lsi;
	union {
		struct {
			__le32 lpol;