From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49164) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZzZSD-0000HA-60 for qemu-devel@nongnu.org; Thu, 19 Nov 2015 19:21:30 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZzZSC-0003Hu-76 for qemu-devel@nongnu.org; Thu, 19 Nov 2015 19:21:29 -0500 Received: from mail.kernel.org ([198.145.29.136]:44525) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZzZSB-0003Gz-Ub for qemu-devel@nongnu.org; Thu, 19 Nov 2015 19:21:28 -0500 From: Ming Lin Date: Thu, 19 Nov 2015 16:21:04 -0800 Message-Id: <1447978868-17138-6-git-send-email-mlin@kernel.org> In-Reply-To: <1447978868-17138-1-git-send-email-mlin@kernel.org> References: <1447978868-17138-1-git-send-email-mlin@kernel.org> Subject: [Qemu-devel] [RFC PATCH 5/9] nvme-vhost: add controller "start" callback List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: linux-nvme@lists.infradead.org Cc: Ming Lin , Christoph Hellwig , qemu-devel@nongnu.org, "Nicholas A. Bellinger" , virtualization@lists.linux-foundation.org From: Ming Lin Signed-off-by: Ming Lin --- drivers/nvme/target/vhost.c | 106 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) diff --git a/drivers/nvme/target/vhost.c b/drivers/nvme/target/vhost.c index 01c44b8..4a147d6 100644 --- a/drivers/nvme/target/vhost.c +++ b/drivers/nvme/target/vhost.c @@ -10,6 +10,35 @@ #define NVMET_VHOST_AQ_DEPTH 256 +enum NvmeCcShift { + CC_MPS_SHIFT = 7, + CC_IOSQES_SHIFT = 16, + CC_IOCQES_SHIFT = 20, +}; + +enum NvmeCcMask { + CC_MPS_MASK = 0xf, + CC_IOSQES_MASK = 0xf, + CC_IOCQES_MASK = 0xf, +}; + +#define NVME_CC_MPS(cc) ((cc >> CC_MPS_SHIFT) & CC_MPS_MASK) +#define NVME_CC_IOSQES(cc) ((cc >> CC_IOSQES_SHIFT) & CC_IOSQES_MASK) +#define NVME_CC_IOCQES(cc) ((cc >> CC_IOCQES_SHIFT) & CC_IOCQES_MASK) + +enum NvmeAqaShift { + AQA_ASQS_SHIFT = 0, + AQA_ACQS_SHIFT = 16, +}; + +enum NvmeAqaMask { + AQA_ASQS_MASK = 0xfff, + AQA_ACQS_MASK = 0xfff, +}; + +#define NVME_AQA_ASQS(aqa) ((aqa >> AQA_ASQS_SHIFT) & AQA_ASQS_MASK) +#define NVME_AQA_ACQS(aqa) ((aqa >> AQA_ACQS_SHIFT) & AQA_ACQS_MASK) + struct nvmet_vhost_ctrl_eventfd { struct file *call; struct eventfd_ctx *call_ctx; @@ -19,12 +48,23 @@ struct nvmet_vhost_ctrl_eventfd { struct nvmet_vhost_cq { struct nvmet_cq cq; + struct nvmet_vhost_ctrl *ctrl; + u32 head; + u32 tail; + u8 phase; + u64 dma_addr; struct eventfd_ctx *eventfd; }; struct nvmet_vhost_sq { struct nvmet_sq sq; + struct nvmet_vhost_ctrl *ctrl; + + u32 head; + u32 tail; + u64 dma_addr; + u16 cqid; }; struct nvmet_vhost_ctrl { @@ -37,12 +77,76 @@ struct nvmet_vhost_ctrl { struct nvmet_vhost_cq **cqs; struct nvmet_vhost_sq **sqs; + struct nvmet_vhost_cq admin_cq; + struct nvmet_vhost_sq admin_sq; u32 aqa; u64 asq; u64 acq; + u16 cqe_size; + u16 sqe_size; + u16 max_prp_ents; + u16 page_bits; + u32 page_size; }; +static int nvmet_vhost_init_cq(struct nvmet_vhost_cq *cq, + struct nvmet_vhost_ctrl *n, u64 dma_addr, + u16 cqid, u16 size, struct eventfd_ctx *eventfd, + u16 vector, u16 irq_enabled) +{ + cq->ctrl = n; + cq->dma_addr = dma_addr; + cq->phase = 1; + cq->head = cq->tail = 0; + cq->eventfd = eventfd; + n->cqs[cqid] = cq; + + nvmet_cq_init(n->ctrl, &cq->cq, cqid, size); + + return 0; +} + +static int nvmet_vhost_init_sq(struct nvmet_vhost_sq *sq, + struct nvmet_vhost_ctrl *n, u64 dma_addr, + u16 sqid, u16 cqid, u16 size) +{ + sq->ctrl = n; + sq->dma_addr = dma_addr; + sq->cqid = cqid; + sq->head = sq->tail = 0; + n->sqs[sqid] = sq; + + nvmet_sq_init(n->ctrl, &sq->sq, sqid, size); + + return 0; +} + +static void nvmet_vhost_start_ctrl(void *opaque) +{ + struct nvmet_vhost_ctrl *n = opaque; + u32 page_bits = NVME_CC_MPS(n->ctrl->cc) + 12; + u32 page_size = 1 << page_bits; + int ret; + + n->page_bits = page_bits; + n->page_size = page_size; + n->max_prp_ents = n->page_size / sizeof(uint64_t); + n->cqe_size = 1 << NVME_CC_IOCQES(n->ctrl->cc); + n->sqe_size = 1 << NVME_CC_IOSQES(n->ctrl->cc); + + nvmet_vhost_init_cq(&n->admin_cq, n, n->acq, 0, + NVME_AQA_ACQS(n->aqa) + 1, n->eventfd[0].call_ctx, + 0, 1); + + ret = nvmet_vhost_init_sq(&n->admin_sq, n, n->asq, 0, 0, + NVME_AQA_ASQS(n->aqa) + 1); + if (ret) { + pr_warn("nvmet_vhost_init_sq failed!!!\n"); + BUG_ON(1); + } +} + static int nvmet_vhost_set_endpoint(struct nvmet_vhost_ctrl *n, struct vhost_nvme_target *c) @@ -67,6 +171,8 @@ nvmet_vhost_set_endpoint(struct nvmet_vhost_ctrl *n, n->cntlid = ctrl->cntlid; n->ctrl = ctrl; n->num_queues = subsys->max_qid + 1; + ctrl->opaque = n; + ctrl->start = nvmet_vhost_start_ctrl; num_queues = ctrl->subsys->max_qid + 1; n->cqs = kzalloc(sizeof(*n->cqs) * num_queues, GFP_KERNEL); -- 1.9.1