All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mark Kettenis <kettenis@openbsd.org>
To: u-boot@lists.denx.de
Cc: sjg@chromium.org, jh80.chung@samsung.com, trini@konsulko.com,
	sven@svenpeter.dev, marcan@marcan.st, bmeng.cn@gmail.com,
	Mark Kettenis <kettenis@openbsd.org>
Subject: [PATCH 4/8] nvme: Introduce driver ops
Date: Fri, 14 Jan 2022 12:04:34 +0100	[thread overview]
Message-ID: <20220114110438.58452-5-kettenis@openbsd.org> (raw)
In-Reply-To: <20220114110438.58452-1-kettenis@openbsd.org>

The NVMe storage controller integrated on Apple SoCs deviates
from the NVMe standard in two aspects.  It uses a "linear"
submission queue and it integrates an NVMMU that needs to be
programmed for each NVMe command.  Introduce driver ops such
that we can set up the linear submission queue and program the
NVMMU in the driver for this strange beast.

Signed-off-by: Mark Kettenis <kettenis@openbsd.org>
---
 drivers/nvme/nvme.c | 45 ++++++++++++++++++---------------------------
 drivers/nvme/nvme.h | 33 +++++++++++++++++++++++++++++++++
 2 files changed, 51 insertions(+), 27 deletions(-)

diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c
index be518ec20b..e2d0f9c668 100644
--- a/drivers/nvme/nvme.c
+++ b/drivers/nvme/nvme.c
@@ -27,33 +27,6 @@
 #define IO_TIMEOUT		30
 #define MAX_PRP_POOL		512
 
-enum nvme_queue_id {
-	NVME_ADMIN_Q,
-	NVME_IO_Q,
-	NVME_Q_NUM,
-};
-
-/*
- * An NVM Express queue. Each device has at least two (one for admin
- * commands and one for I/O commands).
- */
-struct nvme_queue {
-	struct nvme_dev *dev;
-	struct nvme_command *sq_cmds;
-	struct nvme_completion *cqes;
-	wait_queue_head_t sq_full;
-	u32 __iomem *q_db;
-	u16 q_depth;
-	s16 cq_vector;
-	u16 sq_head;
-	u16 sq_tail;
-	u16 cq_head;
-	u16 qid;
-	u8 cq_phase;
-	u8 cqe_seen;
-	unsigned long cmdid_data[];
-};
-
 static int nvme_wait_ready(struct nvme_dev *dev, bool enabled)
 {
 	u32 bit = enabled ? NVME_CSTS_RDY : 0;
@@ -167,12 +140,19 @@ static u16 nvme_read_completion_status(struct nvme_queue *nvmeq, u16 index)
  */
 static void nvme_submit_cmd(struct nvme_queue *nvmeq, struct nvme_command *cmd)
 {
+	struct nvme_ops *ops;
 	u16 tail = nvmeq->sq_tail;
 
 	memcpy(&nvmeq->sq_cmds[tail], cmd, sizeof(*cmd));
 	flush_dcache_range((ulong)&nvmeq->sq_cmds[tail],
 			   (ulong)&nvmeq->sq_cmds[tail] + sizeof(*cmd));
 
+	ops = (struct nvme_ops *)nvmeq->dev->udev->driver->ops;
+	if (ops && ops->submit_cmd) {
+		ops->submit_cmd(nvmeq, cmd);
+		return;
+	}
+
 	if (++tail == nvmeq->q_depth)
 		tail = 0;
 	writel(tail, nvmeq->q_db);
@@ -183,6 +163,7 @@ static int nvme_submit_sync_cmd(struct nvme_queue *nvmeq,
 				struct nvme_command *cmd,
 				u32 *result, unsigned timeout)
 {
+	struct nvme_ops *ops;
 	u16 head = nvmeq->cq_head;
 	u16 phase = nvmeq->cq_phase;
 	u16 status;
@@ -203,6 +184,10 @@ static int nvme_submit_sync_cmd(struct nvme_queue *nvmeq,
 			return -ETIMEDOUT;
 	}
 
+	ops = (struct nvme_ops *)nvmeq->dev->udev->driver->ops;
+	if (ops && ops->complete_cmd)
+		ops->complete_cmd(nvmeq, cmd);
+
 	status >>= 1;
 	if (status) {
 		printf("ERROR: status = %x, phase = %d, head = %d\n",
@@ -243,6 +228,7 @@ static int nvme_submit_admin_cmd(struct nvme_dev *dev, struct nvme_command *cmd,
 static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev,
 					   int qid, int depth)
 {
+	struct nvme_ops *ops;
 	struct nvme_queue *nvmeq = malloc(sizeof(*nvmeq));
 	if (!nvmeq)
 		return NULL;
@@ -268,6 +254,10 @@ static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev,
 	dev->queue_count++;
 	dev->queues[qid] = nvmeq;
 
+	ops = (struct nvme_ops *)dev->udev->driver->ops;
+	if (ops && ops->alloc_queue)
+		ops->alloc_queue(nvmeq);
+
 	return nvmeq;
 
  free_queue:
@@ -821,6 +811,7 @@ int nvme_init(struct udevice *udev)
 	struct nvme_id_ns *id;
 	int ret;
 
+	ndev->udev = udev;
 	INIT_LIST_HEAD(&ndev->namespaces);
 	if (readl(&ndev->bar->csts) == -1) {
 		ret = -ENODEV;
diff --git a/drivers/nvme/nvme.h b/drivers/nvme/nvme.h
index 8e9ae3c7f6..57803b43fd 100644
--- a/drivers/nvme/nvme.h
+++ b/drivers/nvme/nvme.h
@@ -596,6 +596,7 @@ enum {
 
 /* Represents an NVM Express device. Each nvme_dev is a PCI function. */
 struct nvme_dev {
+	struct udevice *udev;
 	struct list_head node;
 	struct nvme_queue **queues;
 	u32 __iomem *dbs;
@@ -622,6 +623,32 @@ struct nvme_dev {
 	u32 nn;
 };
 
+enum nvme_queue_id {
+	NVME_ADMIN_Q,
+	NVME_IO_Q,
+	NVME_Q_NUM,
+};
+
+/*
+ * An NVM Express queue. Each device has at least two (one for admin
+ * commands and one for I/O commands).
+ */
+struct nvme_queue {
+	struct nvme_dev *dev;
+	struct nvme_command *sq_cmds;
+	struct nvme_completion *cqes;
+	u32 __iomem *q_db;
+	u16 q_depth;
+	s16 cq_vector;
+	u16 sq_head;
+	u16 sq_tail;
+	u16 cq_head;
+	u16 qid;
+	u8 cq_phase;
+	u8 cqe_seen;
+	unsigned long cmdid_data[];
+};
+
 /*
  * An NVM Express namespace is equivalent to a SCSI LUN.
  * Each namespace is operated as an independent "device".
@@ -636,6 +663,12 @@ struct nvme_ns {
 	u8 flbas;
 };
 
+struct nvme_ops {
+	int (*alloc_queue)(struct nvme_queue *);
+	void (*submit_cmd)(struct nvme_queue *, struct nvme_command *);
+	void (*complete_cmd)(struct nvme_queue *, struct nvme_command *);
+};
+
 int nvme_init(struct udevice *udev);
 
 #endif /* __DRIVER_NVME_H__ */
-- 
2.34.1


  parent reply	other threads:[~2022-01-14 11:06 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-14 11:04 [PATCH 0/8] Apple M1 NVMe storage support Mark Kettenis
2022-01-14 11:04 ` [PATCH 1/8] nvme: Split out PCI support Mark Kettenis
2022-01-22  1:40   ` Simon Glass
2022-01-22 12:47     ` Mark Kettenis
2022-01-22 13:18       ` Simon Glass
2022-01-22 14:57         ` Mark Kettenis
2022-01-14 11:04 ` [PATCH 2/8] mailbox: apple: Add driver for Apple IOP mailbox Mark Kettenis
2022-01-22  1:40   ` Simon Glass
2022-01-22 13:54     ` Mark Kettenis
2022-01-22 17:17       ` Simon Glass
2022-01-14 11:04 ` [PATCH 3/8] arm: apple: Add RTKit support Mark Kettenis
2022-01-22  1:40   ` Simon Glass
2022-01-22 13:59     ` Mark Kettenis
2022-01-22 17:17       ` Simon Glass
2022-01-22 19:31         ` Mark Kettenis
2022-01-14 11:04 ` Mark Kettenis [this message]
2022-01-22  1:40   ` [PATCH 4/8] nvme: Introduce driver ops Simon Glass
2022-01-22 13:33     ` Mark Kettenis
2022-01-22 17:17       ` Simon Glass
2022-01-14 11:04 ` [PATCH 5/8] nvme: Add shutdown function Mark Kettenis
2022-01-22  1:40   ` Simon Glass
2022-01-14 11:04 ` [PATCH 6/8] power: domain: apple: Add reset support Mark Kettenis
2022-01-22  1:40   ` Simon Glass
2022-01-22 14:11     ` Mark Kettenis
2022-01-22 17:17       ` Simon Glass
2022-01-22 19:35         ` Mark Kettenis
2022-01-14 11:04 ` [PATCH 7/8] nvme: apple: Add driver for Apple NVMe storage controller Mark Kettenis
2022-01-22  1:40   ` Simon Glass
2022-01-22 14:45     ` Mark Kettenis
2022-01-22 17:17       ` Simon Glass
2022-01-22 17:41         ` Mark Kettenis
2022-01-22 18:28           ` Simon Glass
2022-01-14 11:04 ` [PATCH 8/8] configs: apple: Add NVMe boot target Mark Kettenis

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220114110438.58452-5-kettenis@openbsd.org \
    --to=kettenis@openbsd.org \
    --cc=bmeng.cn@gmail.com \
    --cc=jh80.chung@samsung.com \
    --cc=marcan@marcan.st \
    --cc=sjg@chromium.org \
    --cc=sven@svenpeter.dev \
    --cc=trini@konsulko.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.