Commit 94cc781f authored by Christoph Hellwig's avatar Christoph Hellwig
Browse files

nvme: move OPAL setup from PCIe to core



Nothing about the TCG Opal support is PCIe transport specific, so move it
to the core code.  For this nvme_init_ctrl_finish grows a new
was_suspended argument that allows the transport driver to tell the OPAL
code if the controller came out of a suspend cycle.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarKeith Busch <kbusch@kernel.org>
Reviewed-by: default avatarSagi Grimberg <sagi@grimberg.me>
Reviewed-by: default avatarChaitanya Kulkarni <kch@nvidia.com>
Reviewed-by: default avatarJames Smart <jsmart2021@gmail.com>
Tested-by Gerd Bayer <gbayer@linxu.ibm.com>
parent 1e37a307
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -1102,7 +1102,7 @@ static void apple_nvme_reset_work(struct work_struct *work)
		goto out;
		goto out;
	}
	}


	ret = nvme_init_ctrl_finish(&anv->ctrl);
	ret = nvme_init_ctrl_finish(&anv->ctrl, false);
	if (ret)
	if (ret)
		goto out;
		goto out;


+22 −3
Original line number Original line Diff line number Diff line
@@ -2192,7 +2192,7 @@ const struct pr_ops nvme_pr_ops = {
};
};


#ifdef CONFIG_BLK_SED_OPAL
#ifdef CONFIG_BLK_SED_OPAL
int nvme_sec_submit(void *data, u16 spsp, u8 secp, void *buffer, size_t len,
static int nvme_sec_submit(void *data, u16 spsp, u8 secp, void *buffer, size_t len,
		bool send)
		bool send)
{
{
	struct nvme_ctrl *ctrl = data;
	struct nvme_ctrl *ctrl = data;
@@ -2209,7 +2209,23 @@ int nvme_sec_submit(void *data, u16 spsp, u8 secp, void *buffer, size_t len,
	return __nvme_submit_sync_cmd(ctrl->admin_q, &cmd, NULL, buffer, len,
	return __nvme_submit_sync_cmd(ctrl->admin_q, &cmd, NULL, buffer, len,
			NVME_QID_ANY, 1, 0);
			NVME_QID_ANY, 1, 0);
}
}
EXPORT_SYMBOL_GPL(nvme_sec_submit);

static void nvme_configure_opal(struct nvme_ctrl *ctrl, bool was_suspended)
{
	if (ctrl->oacs & NVME_CTRL_OACS_SEC_SUPP) {
		if (!ctrl->opal_dev)
			ctrl->opal_dev = init_opal_dev(ctrl, &nvme_sec_submit);
		else if (was_suspended)
			opal_unlock_from_suspend(ctrl->opal_dev);
	} else {
		free_opal_dev(ctrl->opal_dev);
		ctrl->opal_dev = NULL;
	}
}
#else
static void nvme_configure_opal(struct nvme_ctrl *ctrl, bool was_suspended)
{
}
#endif /* CONFIG_BLK_SED_OPAL */
#endif /* CONFIG_BLK_SED_OPAL */


#ifdef CONFIG_BLK_DEV_ZONED
#ifdef CONFIG_BLK_DEV_ZONED
@@ -3242,7 +3258,7 @@ static int nvme_init_identify(struct nvme_ctrl *ctrl)
 * register in our nvme_ctrl structure.  This should be called as soon as
 * register in our nvme_ctrl structure.  This should be called as soon as
 * the admin queue is fully up and running.
 * the admin queue is fully up and running.
 */
 */
int nvme_init_ctrl_finish(struct nvme_ctrl *ctrl)
int nvme_init_ctrl_finish(struct nvme_ctrl *ctrl, bool was_suspended)
{
{
	int ret;
	int ret;


@@ -3273,6 +3289,8 @@ int nvme_init_ctrl_finish(struct nvme_ctrl *ctrl)
	if (ret < 0)
	if (ret < 0)
		return ret;
		return ret;


	nvme_configure_opal(ctrl, was_suspended);

	if (!ctrl->identified && !nvme_discovery_ctrl(ctrl)) {
	if (!ctrl->identified && !nvme_discovery_ctrl(ctrl)) {
		/*
		/*
		 * Do not return errors unless we are in a controller reset,
		 * Do not return errors unless we are in a controller reset,
@@ -5007,6 +5025,7 @@ static void nvme_free_ctrl(struct device *dev)
	nvme_auth_stop(ctrl);
	nvme_auth_stop(ctrl);
	nvme_auth_free(ctrl);
	nvme_auth_free(ctrl);
	__free_page(ctrl->discard_page);
	__free_page(ctrl->discard_page);
	free_opal_dev(ctrl->opal_dev);


	if (subsys) {
	if (subsys) {
		mutex_lock(&nvme_subsystems_lock);
		mutex_lock(&nvme_subsystems_lock);
+1 −1
Original line number Original line Diff line number Diff line
@@ -3107,7 +3107,7 @@ nvme_fc_create_association(struct nvme_fc_ctrl *ctrl)


	nvme_start_admin_queue(&ctrl->ctrl);
	nvme_start_admin_queue(&ctrl->ctrl);


	ret = nvme_init_ctrl_finish(&ctrl->ctrl);
	ret = nvme_init_ctrl_finish(&ctrl->ctrl, false);
	if (ret || test_bit(ASSOC_FAILED, &ctrl->flags))
	if (ret || test_bit(ASSOC_FAILED, &ctrl->flags))
		goto out_disconnect_admin_queue;
		goto out_disconnect_admin_queue;


+1 −4
Original line number Original line Diff line number Diff line
@@ -736,7 +736,7 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev,
void nvme_uninit_ctrl(struct nvme_ctrl *ctrl);
void nvme_uninit_ctrl(struct nvme_ctrl *ctrl);
void nvme_start_ctrl(struct nvme_ctrl *ctrl);
void nvme_start_ctrl(struct nvme_ctrl *ctrl);
void nvme_stop_ctrl(struct nvme_ctrl *ctrl);
void nvme_stop_ctrl(struct nvme_ctrl *ctrl);
int nvme_init_ctrl_finish(struct nvme_ctrl *ctrl);
int nvme_init_ctrl_finish(struct nvme_ctrl *ctrl, bool was_suspended);
int nvme_alloc_admin_tag_set(struct nvme_ctrl *ctrl, struct blk_mq_tag_set *set,
int nvme_alloc_admin_tag_set(struct nvme_ctrl *ctrl, struct blk_mq_tag_set *set,
		const struct blk_mq_ops *ops, unsigned int flags,
		const struct blk_mq_ops *ops, unsigned int flags,
		unsigned int cmd_size);
		unsigned int cmd_size);
@@ -748,9 +748,6 @@ void nvme_remove_io_tag_set(struct nvme_ctrl *ctrl);


void nvme_remove_namespaces(struct nvme_ctrl *ctrl);
void nvme_remove_namespaces(struct nvme_ctrl *ctrl);


int nvme_sec_submit(void *data, u16 spsp, u8 secp, void *buffer, size_t len,
		bool send);

void nvme_complete_async_event(struct nvme_ctrl *ctrl, __le16 status,
void nvme_complete_async_event(struct nvme_ctrl *ctrl, __le16 status,
		volatile union nvme_result *res);
		volatile union nvme_result *res);


+1 −13
Original line number Original line Diff line number Diff line
@@ -2772,7 +2772,6 @@ static void nvme_pci_free_ctrl(struct nvme_ctrl *ctrl)
	nvme_free_tagset(dev);
	nvme_free_tagset(dev);
	if (dev->ctrl.admin_q)
	if (dev->ctrl.admin_q)
		blk_put_queue(dev->ctrl.admin_q);
		blk_put_queue(dev->ctrl.admin_q);
	free_opal_dev(dev->ctrl.opal_dev);
	mempool_destroy(dev->iod_mempool);
	mempool_destroy(dev->iod_mempool);
	put_device(dev->dev);
	put_device(dev->dev);
	kfree(dev->queues);
	kfree(dev->queues);
@@ -2866,21 +2865,10 @@ static void nvme_reset_work(struct work_struct *work)
	 */
	 */
	dev->ctrl.max_integrity_segments = 1;
	dev->ctrl.max_integrity_segments = 1;


	result = nvme_init_ctrl_finish(&dev->ctrl);
	result = nvme_init_ctrl_finish(&dev->ctrl, was_suspend);
	if (result)
	if (result)
		goto out;
		goto out;


	if (dev->ctrl.oacs & NVME_CTRL_OACS_SEC_SUPP) {
		if (!dev->ctrl.opal_dev)
			dev->ctrl.opal_dev =
				init_opal_dev(&dev->ctrl, &nvme_sec_submit);
		else if (was_suspend)
			opal_unlock_from_suspend(dev->ctrl.opal_dev);
	} else {
		free_opal_dev(dev->ctrl.opal_dev);
		dev->ctrl.opal_dev = NULL;
	}

	if (dev->ctrl.oacs & NVME_CTRL_OACS_DBBUF_SUPP) {
	if (dev->ctrl.oacs & NVME_CTRL_OACS_DBBUF_SUPP) {
		result = nvme_dbbuf_dma_alloc(dev);
		result = nvme_dbbuf_dma_alloc(dev);
		if (result)
		if (result)
Loading