Commit 4b8178ec authored by Dean Balandin's avatar Dean Balandin Committed by David S. Miller
Browse files

nvme-tcp-offload: Add device scan implementation



As part of create_ctrl(), it scans the registered devices and calls
the claim_dev op on each of them, to find the first devices that matches
the connection params. Once the correct devices is found (claim_dev
returns true), we raise the refcnt of that device and return that device
as the device to be used for ctrl currently being created.

Acked-by: default avatarIgor Russkikh <irusskikh@marvell.com>
Signed-off-by: default avatarDean Balandin <dbalandin@marvell.com>
Signed-off-by: default avatarPrabhakar Kushwaha <pkushwaha@marvell.com>
Signed-off-by: default avatarOmkar Kulkarni <okulkarni@marvell.com>
Signed-off-by: default avatarMichal Kalderon <mkalderon@marvell.com>
Signed-off-by: default avatarAriel Elior <aelior@marvell.com>
Signed-off-by: default avatarShai Malin <smalin@marvell.com>
Reviewed-by: default avatarHimanshu Madhani <himanshu.madhani@oracle.com>
Reviewed-by: default avatarHannes Reinecke <hare@suse.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent af527935
Loading
Loading
Loading
Loading
+77 −0
Original line number Diff line number Diff line
@@ -13,6 +13,11 @@
static LIST_HEAD(nvme_tcp_ofld_devices);
static DEFINE_MUTEX(nvme_tcp_ofld_devices_mutex);

static inline struct nvme_tcp_ofld_ctrl *to_tcp_ofld_ctrl(struct nvme_ctrl *nctrl)
{
	return container_of(nctrl, struct nvme_tcp_ofld_ctrl, nctrl);
}

/**
 * nvme_tcp_ofld_register_dev() - NVMeTCP Offload Library registration
 * function.
@@ -96,6 +101,77 @@ void nvme_tcp_ofld_req_done(struct nvme_tcp_ofld_req *req,
	/* Placeholder - complete request with/without error */
}

static struct nvme_tcp_ofld_dev *
nvme_tcp_ofld_lookup_dev(struct nvme_tcp_ofld_ctrl *ctrl)
{
	struct nvme_tcp_ofld_dev *dev;

	mutex_lock(&nvme_tcp_ofld_devices_mutex);
	list_for_each_entry(dev, &nvme_tcp_ofld_devices, entry) {
		if (dev->ops->claim_dev(dev, ctrl))
			goto out;
	}

	dev = NULL;
out:
	mutex_unlock(&nvme_tcp_ofld_devices_mutex);

	return dev;
}

static struct nvme_ctrl *
nvme_tcp_ofld_create_ctrl(struct device *ndev, struct nvmf_ctrl_options *opts)
{
	struct nvme_tcp_ofld_ctrl *ctrl;
	struct nvme_tcp_ofld_dev *dev;
	struct nvme_ctrl *nctrl;
	int rc = 0;

	ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
	if (!ctrl)
		return ERR_PTR(-ENOMEM);

	nctrl = &ctrl->nctrl;

	/* Init nvme_tcp_ofld_ctrl and nvme_ctrl params based on received opts */

	/* Find device that can reach the dest addr */
	dev = nvme_tcp_ofld_lookup_dev(ctrl);
	if (!dev) {
		pr_info("no device found for addr %s:%s.\n",
			opts->traddr, opts->trsvcid);
		rc = -EINVAL;
		goto out_free_ctrl;
	}

	/* Increase driver refcnt */
	if (!try_module_get(dev->ops->module)) {
		pr_err("try_module_get failed\n");
		dev = NULL;
		goto out_free_ctrl;
	}

	ctrl->dev = dev;

	if (ctrl->dev->ops->max_hw_sectors)
		nctrl->max_hw_sectors = ctrl->dev->ops->max_hw_sectors;
	if (ctrl->dev->ops->max_segments)
		nctrl->max_segments = ctrl->dev->ops->max_segments;

	/* Init queues */

	/* Call nvme_init_ctrl */

	/* Setup ctrl */

	return nctrl;

out_free_ctrl:
	kfree(ctrl);

	return ERR_PTR(rc);
}

static struct nvmf_transport_ops nvme_tcp_ofld_transport = {
	.name		= "tcp_offload",
	.module		= THIS_MODULE,
@@ -105,6 +181,7 @@ static struct nvmf_transport_ops nvme_tcp_ofld_transport = {
			  NVMF_OPT_RECONNECT_DELAY | NVMF_OPT_HDR_DIGEST |
			  NVMF_OPT_DATA_DIGEST | NVMF_OPT_NR_POLL_QUEUES |
			  NVMF_OPT_TOS,
	.create_ctrl	= nvme_tcp_ofld_create_ctrl,
};

static int __init nvme_tcp_ofld_init_module(void)