mirror of
https://github.com/home-assistant/operating-system.git
synced 2025-07-27 06:56:29 +00:00
NVMe patches are applied for all Raspberry Pi based boards now (#1959)
This commit is contained in:
parent
ad2f3a3570
commit
306c07b1b1
@ -1,51 +0,0 @@
|
|||||||
From 78924e9cf8c4af0baafcb2e7224bf04ad65276de Mon Sep 17 00:00:00 2001
|
|
||||||
Message-Id: <78924e9cf8c4af0baafcb2e7224bf04ad65276de.1650924333.git.stefan@agner.ch>
|
|
||||||
In-Reply-To: <78704bc154d695ee16fdf8396f4d60b740190014.1650924333.git.stefan@agner.ch>
|
|
||||||
References: <78704bc154d695ee16fdf8396f4d60b740190014.1650924333.git.stefan@agner.ch>
|
|
||||||
From: Stefan Agner <stefan@agner.ch>
|
|
||||||
Date: Thu, 23 Sep 2021 23:52:44 +0200
|
|
||||||
Subject: [PATCH 3/5] nvme: improve readability of nvme_setup_prps()
|
|
||||||
|
|
||||||
Improve readability by introducing consts, reuse consts where
|
|
||||||
appropriate and adding variables with discriptive name.
|
|
||||||
|
|
||||||
Signed-off-by: Stefan Agner <stefan@agner.ch>
|
|
||||||
---
|
|
||||||
drivers/nvme/nvme.c | 10 +++++-----
|
|
||||||
1 file changed, 5 insertions(+), 5 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c
|
|
||||||
index 3bda491e12..1601651449 100644
|
|
||||||
--- a/drivers/nvme/nvme.c
|
|
||||||
+++ b/drivers/nvme/nvme.c
|
|
||||||
@@ -76,12 +76,12 @@ static int nvme_wait_ready(struct nvme_dev *dev, bool enabled)
|
|
||||||
static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2,
|
|
||||||
int total_len, u64 dma_addr)
|
|
||||||
{
|
|
||||||
- u32 page_size = dev->page_size;
|
|
||||||
+ const u32 page_size = dev->page_size;
|
|
||||||
+ const u32 prps_per_page = (page_size >> 3) - 1;
|
|
||||||
int offset = dma_addr & (page_size - 1);
|
|
||||||
u64 *prp_pool;
|
|
||||||
int length = total_len;
|
|
||||||
int i, nprps;
|
|
||||||
- u32 prps_per_page = (page_size >> 3) - 1;
|
|
||||||
u32 num_pages;
|
|
||||||
|
|
||||||
length -= (page_size - offset);
|
|
||||||
@@ -119,9 +119,9 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2,
|
|
||||||
prp_pool = dev->prp_pool;
|
|
||||||
i = 0;
|
|
||||||
while (nprps) {
|
|
||||||
- if (i == ((page_size >> 3) - 1)) {
|
|
||||||
- *(prp_pool + i) = cpu_to_le64((ulong)prp_pool +
|
|
||||||
- page_size);
|
|
||||||
+ if (i == prps_per_page) {
|
|
||||||
+ u64 next_prp_list = (u64)prp_pool + page_size;
|
|
||||||
+ *(prp_pool + i) = cpu_to_le64(next_prp_list);
|
|
||||||
i = 0;
|
|
||||||
prp_pool += page_size;
|
|
||||||
}
|
|
||||||
--
|
|
||||||
2.36.0
|
|
||||||
|
|
@ -1,263 +0,0 @@
|
|||||||
From e040d976ecbdd8071bbcb73d78e17ababa88c51f Mon Sep 17 00:00:00 2001
|
|
||||||
Message-Id: <e040d976ecbdd8071bbcb73d78e17ababa88c51f.1650924333.git.stefan@agner.ch>
|
|
||||||
In-Reply-To: <78704bc154d695ee16fdf8396f4d60b740190014.1650924333.git.stefan@agner.ch>
|
|
||||||
References: <78704bc154d695ee16fdf8396f4d60b740190014.1650924333.git.stefan@agner.ch>
|
|
||||||
From: Stefan Agner <stefan@agner.ch>
|
|
||||||
Date: Thu, 23 Sep 2021 23:58:35 +0200
|
|
||||||
Subject: [PATCH 4/5] nvme: Use pointer for CPU addressed buffers
|
|
||||||
|
|
||||||
Pass buffers which use CPU addressing as void pointers. This aligns with
|
|
||||||
DMA APIs which use void pointers as argument. It will avoid unnecessary
|
|
||||||
type casts when adding support bus address translations.
|
|
||||||
|
|
||||||
Signed-off-by: Stefan Agner <stefan@agner.ch>
|
|
||||||
---
|
|
||||||
drivers/nvme/nvme.c | 50 ++++++++++++++++++++--------------------
|
|
||||||
drivers/nvme/nvme_show.c | 4 ++--
|
|
||||||
include/nvme.h | 12 +++++-----
|
|
||||||
3 files changed, 33 insertions(+), 33 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c
|
|
||||||
index 1601651449..6ab94ada7e 100644
|
|
||||||
--- a/drivers/nvme/nvme.c
|
|
||||||
+++ b/drivers/nvme/nvme.c
|
|
||||||
@@ -74,11 +74,11 @@ static int nvme_wait_ready(struct nvme_dev *dev, bool enabled)
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2,
|
|
||||||
- int total_len, u64 dma_addr)
|
|
||||||
+ int total_len, void *buffer)
|
|
||||||
{
|
|
||||||
const u32 page_size = dev->page_size;
|
|
||||||
const u32 prps_per_page = (page_size >> 3) - 1;
|
|
||||||
- int offset = dma_addr & (page_size - 1);
|
|
||||||
+ int offset = (uintptr_t)buffer & (page_size - 1);
|
|
||||||
u64 *prp_pool;
|
|
||||||
int length = total_len;
|
|
||||||
int i, nprps;
|
|
||||||
@@ -92,10 +92,10 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2,
|
|
||||||
}
|
|
||||||
|
|
||||||
if (length)
|
|
||||||
- dma_addr += (page_size - offset);
|
|
||||||
+ buffer += (page_size - offset);
|
|
||||||
|
|
||||||
if (length <= page_size) {
|
|
||||||
- *prp2 = dma_addr;
|
|
||||||
+ *prp2 = (u64)buffer;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -125,11 +125,11 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2,
|
|
||||||
i = 0;
|
|
||||||
prp_pool += page_size;
|
|
||||||
}
|
|
||||||
- *(prp_pool + i++) = cpu_to_le64(dma_addr);
|
|
||||||
- dma_addr += page_size;
|
|
||||||
+ *(prp_pool + i++) = cpu_to_le64((u64)buffer);
|
|
||||||
+ buffer += page_size;
|
|
||||||
nprps--;
|
|
||||||
}
|
|
||||||
- *prp2 = (ulong)dev->prp_pool;
|
|
||||||
+ *prp2 = (u64)dev->prp_pool;
|
|
||||||
|
|
||||||
flush_dcache_range((ulong)dev->prp_pool, (ulong)dev->prp_pool +
|
|
||||||
dev->prp_entry_num * sizeof(u64));
|
|
||||||
@@ -450,42 +450,42 @@ static int nvme_alloc_sq(struct nvme_dev *dev, u16 qid,
|
|
||||||
}
|
|
||||||
|
|
||||||
int nvme_identify(struct nvme_dev *dev, unsigned nsid,
|
|
||||||
- unsigned cns, dma_addr_t dma_addr)
|
|
||||||
+ unsigned int cns, void *buffer)
|
|
||||||
{
|
|
||||||
struct nvme_command c;
|
|
||||||
u32 page_size = dev->page_size;
|
|
||||||
- int offset = dma_addr & (page_size - 1);
|
|
||||||
+ int offset = (uintptr_t)buffer & (page_size - 1);
|
|
||||||
int length = sizeof(struct nvme_id_ctrl);
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
memset(&c, 0, sizeof(c));
|
|
||||||
c.identify.opcode = nvme_admin_identify;
|
|
||||||
c.identify.nsid = cpu_to_le32(nsid);
|
|
||||||
- c.identify.prp1 = cpu_to_le64(dma_addr);
|
|
||||||
+ c.identify.prp1 = cpu_to_le64((u64)buffer);
|
|
||||||
|
|
||||||
length -= (page_size - offset);
|
|
||||||
if (length <= 0) {
|
|
||||||
c.identify.prp2 = 0;
|
|
||||||
} else {
|
|
||||||
- dma_addr += (page_size - offset);
|
|
||||||
- c.identify.prp2 = cpu_to_le64(dma_addr);
|
|
||||||
+ buffer += (page_size - offset);
|
|
||||||
+ c.identify.prp2 = cpu_to_le64((u64)buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
c.identify.cns = cpu_to_le32(cns);
|
|
||||||
|
|
||||||
- invalidate_dcache_range(dma_addr,
|
|
||||||
- dma_addr + sizeof(struct nvme_id_ctrl));
|
|
||||||
+ invalidate_dcache_range((uintptr_t)buffer,
|
|
||||||
+ (uintptr_t)buffer + sizeof(struct nvme_id_ctrl));
|
|
||||||
|
|
||||||
ret = nvme_submit_admin_cmd(dev, &c, NULL);
|
|
||||||
if (!ret)
|
|
||||||
- invalidate_dcache_range(dma_addr,
|
|
||||||
- dma_addr + sizeof(struct nvme_id_ctrl));
|
|
||||||
+ invalidate_dcache_range((uintptr_t)buffer,
|
|
||||||
+ (uintptr_t)buffer + sizeof(struct nvme_id_ctrl));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid,
|
|
||||||
- dma_addr_t dma_addr, u32 *result)
|
|
||||||
+ void *buffer, u32 *result)
|
|
||||||
{
|
|
||||||
struct nvme_command c;
|
|
||||||
int ret;
|
|
||||||
@@ -493,7 +493,7 @@ int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid,
|
|
||||||
memset(&c, 0, sizeof(c));
|
|
||||||
c.features.opcode = nvme_admin_get_features;
|
|
||||||
c.features.nsid = cpu_to_le32(nsid);
|
|
||||||
- c.features.prp1 = cpu_to_le64(dma_addr);
|
|
||||||
+ c.features.prp1 = cpu_to_le64((u64)buffer);
|
|
||||||
c.features.fid = cpu_to_le32(fid);
|
|
||||||
|
|
||||||
ret = nvme_submit_admin_cmd(dev, &c, result);
|
|
||||||
@@ -513,13 +513,13 @@ int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid,
|
|
||||||
}
|
|
||||||
|
|
||||||
int nvme_set_features(struct nvme_dev *dev, unsigned fid, unsigned dword11,
|
|
||||||
- dma_addr_t dma_addr, u32 *result)
|
|
||||||
+ void *buffer, u32 *result)
|
|
||||||
{
|
|
||||||
struct nvme_command c;
|
|
||||||
|
|
||||||
memset(&c, 0, sizeof(c));
|
|
||||||
c.features.opcode = nvme_admin_set_features;
|
|
||||||
- c.features.prp1 = cpu_to_le64(dma_addr);
|
|
||||||
+ c.features.prp1 = cpu_to_le64((u64)buffer);
|
|
||||||
c.features.fid = cpu_to_le32(fid);
|
|
||||||
c.features.dword11 = cpu_to_le32(dword11);
|
|
||||||
|
|
||||||
@@ -570,7 +570,7 @@ static int nvme_set_queue_count(struct nvme_dev *dev, int count)
|
|
||||||
u32 q_count = (count - 1) | ((count - 1) << 16);
|
|
||||||
|
|
||||||
status = nvme_set_features(dev, NVME_FEAT_NUM_QUEUES,
|
|
||||||
- q_count, 0, &result);
|
|
||||||
+ q_count, NULL, &result);
|
|
||||||
|
|
||||||
if (status < 0)
|
|
||||||
return status;
|
|
||||||
@@ -622,7 +622,7 @@ static int nvme_get_info_from_identify(struct nvme_dev *dev)
|
|
||||||
if (!ctrl)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
- ret = nvme_identify(dev, 0, 1, (dma_addr_t)(long)ctrl);
|
|
||||||
+ ret = nvme_identify(dev, 0, 1, ctrl);
|
|
||||||
if (ret) {
|
|
||||||
free(ctrl);
|
|
||||||
return -EIO;
|
|
||||||
@@ -708,7 +708,7 @@ static int nvme_blk_probe(struct udevice *udev)
|
|
||||||
ns->dev = ndev;
|
|
||||||
/* extract the namespace id from the block device name */
|
|
||||||
ns->ns_id = trailing_strtol(udev->name);
|
|
||||||
- if (nvme_identify(ndev, ns->ns_id, 0, (dma_addr_t)(long)id)) {
|
|
||||||
+ if (nvme_identify(ndev, ns->ns_id, 0, id)) {
|
|
||||||
free(id);
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
@@ -743,7 +743,7 @@ static ulong nvme_blk_rw(struct udevice *udev, lbaint_t blknr,
|
|
||||||
u64 prp2;
|
|
||||||
u64 total_len = blkcnt << desc->log2blksz;
|
|
||||||
u64 temp_len = total_len;
|
|
||||||
- uintptr_t temp_buffer = (uintptr_t)buffer;
|
|
||||||
+ void *temp_buffer = buffer;
|
|
||||||
|
|
||||||
u64 slba = blknr;
|
|
||||||
u16 lbas = 1 << (dev->max_transfer_shift - ns->lba_shift);
|
|
||||||
@@ -890,7 +890,7 @@ static int nvme_probe(struct udevice *udev)
|
|
||||||
char name[20];
|
|
||||||
|
|
||||||
memset(id, 0, sizeof(*id));
|
|
||||||
- if (nvme_identify(ndev, i, 0, (dma_addr_t)(long)id)) {
|
|
||||||
+ if (nvme_identify(ndev, i, 0, id)) {
|
|
||||||
ret = -EIO;
|
|
||||||
goto free_id;
|
|
||||||
}
|
|
||||||
diff --git a/drivers/nvme/nvme_show.c b/drivers/nvme/nvme_show.c
|
|
||||||
index 15e459da1a..c30adfada5 100644
|
|
||||||
--- a/drivers/nvme/nvme_show.c
|
|
||||||
+++ b/drivers/nvme/nvme_show.c
|
|
||||||
@@ -111,14 +111,14 @@ int nvme_print_info(struct udevice *udev)
|
|
||||||
ALLOC_CACHE_ALIGN_BUFFER(char, buf_ctrl, sizeof(struct nvme_id_ctrl));
|
|
||||||
struct nvme_id_ctrl *ctrl = (struct nvme_id_ctrl *)buf_ctrl;
|
|
||||||
|
|
||||||
- if (nvme_identify(dev, 0, 1, (dma_addr_t)(long)ctrl))
|
|
||||||
+ if (nvme_identify(dev, 0, 1, ctrl))
|
|
||||||
return -EIO;
|
|
||||||
|
|
||||||
print_optional_admin_cmd(le16_to_cpu(ctrl->oacs), ns->devnum);
|
|
||||||
print_optional_nvm_cmd(le16_to_cpu(ctrl->oncs), ns->devnum);
|
|
||||||
print_format_nvme_attributes(ctrl->fna, ns->devnum);
|
|
||||||
|
|
||||||
- if (nvme_identify(dev, ns->ns_id, 0, (dma_addr_t)(long)id))
|
|
||||||
+ if (nvme_identify(dev, ns->ns_id, 0, id))
|
|
||||||
return -EIO;
|
|
||||||
|
|
||||||
print_formats(id, ns);
|
|
||||||
diff --git a/include/nvme.h b/include/nvme.h
|
|
||||||
index 2cdf8ce320..8ff823cd81 100644
|
|
||||||
--- a/include/nvme.h
|
|
||||||
+++ b/include/nvme.h
|
|
||||||
@@ -18,12 +18,12 @@ struct nvme_dev;
|
|
||||||
* @dev: NVMe controller device
|
|
||||||
* @nsid: 0 for controller, namespace id for namespace to identify
|
|
||||||
* @cns: 1 for controller, 0 for namespace
|
|
||||||
- * @dma_addr: dma buffer address to store the identify result
|
|
||||||
+ * @buffer: dma buffer address to store the identify result
|
|
||||||
* @return: 0 on success, -ETIMEDOUT on command execution timeout,
|
|
||||||
* -EIO on command execution fails
|
|
||||||
*/
|
|
||||||
int nvme_identify(struct nvme_dev *dev, unsigned nsid,
|
|
||||||
- unsigned cns, dma_addr_t dma_addr);
|
|
||||||
+ unsigned int cns, void *buffer);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* nvme_get_features - retrieve the attributes of the feature specified
|
|
||||||
@@ -33,13 +33,13 @@ int nvme_identify(struct nvme_dev *dev, unsigned nsid,
|
|
||||||
* @dev: NVMe controller device
|
|
||||||
* @fid: feature id to provide data
|
|
||||||
* @nsid: namespace id the command applies to
|
|
||||||
- * @dma_addr: data structure used as part of the specified feature
|
|
||||||
+ * @buffer: data structure used as part of the specified feature
|
|
||||||
* @result: command-specific result in the completion queue entry
|
|
||||||
* @return: 0 on success, -ETIMEDOUT on command execution timeout,
|
|
||||||
* -EIO on command execution fails
|
|
||||||
*/
|
|
||||||
int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid,
|
|
||||||
- dma_addr_t dma_addr, u32 *result);
|
|
||||||
+ void *buffer, u32 *result);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* nvme_set_features - specify the attributes of the feature indicated
|
|
||||||
@@ -49,13 +49,13 @@ int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid,
|
|
||||||
* @dev: NVMe controller device
|
|
||||||
* @fid: feature id to provide data
|
|
||||||
* @dword11: command-specific input parameter
|
|
||||||
- * @dma_addr: data structure used as part of the specified feature
|
|
||||||
+ * @buffer: data structure used as part of the specified feature
|
|
||||||
* @result: command-specific result in the completion queue entry
|
|
||||||
* @return: 0 on success, -ETIMEDOUT on command execution timeout,
|
|
||||||
* -EIO on command execution fails
|
|
||||||
*/
|
|
||||||
int nvme_set_features(struct nvme_dev *dev, unsigned fid, unsigned dword11,
|
|
||||||
- dma_addr_t dma_addr, u32 *result);
|
|
||||||
+ void *buffer, u32 *result);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* nvme_scan_namespace - scan all namespaces attached to NVMe controllers
|
|
||||||
--
|
|
||||||
2.36.0
|
|
||||||
|
|
@ -1,198 +0,0 @@
|
|||||||
From c4736c35141e519d15430660e17c274e142e886d Mon Sep 17 00:00:00 2001
|
|
||||||
Message-Id: <c4736c35141e519d15430660e17c274e142e886d.1650924333.git.stefan@agner.ch>
|
|
||||||
In-Reply-To: <78704bc154d695ee16fdf8396f4d60b740190014.1650924333.git.stefan@agner.ch>
|
|
||||||
References: <78704bc154d695ee16fdf8396f4d60b740190014.1650924333.git.stefan@agner.ch>
|
|
||||||
From: Stefan Agner <stefan@agner.ch>
|
|
||||||
Date: Fri, 24 Sep 2021 00:27:39 +0200
|
|
||||||
Subject: [PATCH 5/5] nvme: translate virtual addresses into the bus's address
|
|
||||||
space
|
|
||||||
|
|
||||||
So far we've been content with passing physical/CPU addresses when
|
|
||||||
configuring memory addresses into NVMe controllers, but not all
|
|
||||||
platforms have buses with transparent mappings. Specifically the
|
|
||||||
Raspberry Pi 4 might introduce an offset to memory accesses incoming
|
|
||||||
from its PCIe port.
|
|
||||||
|
|
||||||
Introduce nvme_virt_to_bus() and nvme_bus_to_virt() to cater with these
|
|
||||||
limitations, and make sure we don't break non DM users.
|
|
||||||
For devices where PCIe's view of host memory doesn't match the memory
|
|
||||||
as seen by the CPU.
|
|
||||||
|
|
||||||
A similar change has been introduced for XHCI controller with
|
|
||||||
commit 1a474559d90a ("xhci: translate virtual addresses into the bus's
|
|
||||||
address space").
|
|
||||||
|
|
||||||
Signed-off-by: Stefan Agner <stefan@agner.ch>
|
|
||||||
---
|
|
||||||
drivers/nvme/nvme.c | 32 ++++++++++++++++++--------------
|
|
||||||
drivers/nvme/nvme.h | 15 +++++++++++++++
|
|
||||||
2 files changed, 33 insertions(+), 14 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c
|
|
||||||
index 6ab94ada7e..dd190bd654 100644
|
|
||||||
--- a/drivers/nvme/nvme.c
|
|
||||||
+++ b/drivers/nvme/nvme.c
|
|
||||||
@@ -95,7 +95,7 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2,
|
|
||||||
buffer += (page_size - offset);
|
|
||||||
|
|
||||||
if (length <= page_size) {
|
|
||||||
- *prp2 = (u64)buffer;
|
|
||||||
+ *prp2 = nvme_virt_to_bus(dev, buffer);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -120,16 +120,16 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2,
|
|
||||||
i = 0;
|
|
||||||
while (nprps) {
|
|
||||||
if (i == prps_per_page) {
|
|
||||||
- u64 next_prp_list = (u64)prp_pool + page_size;
|
|
||||||
- *(prp_pool + i) = cpu_to_le64(next_prp_list);
|
|
||||||
+ u64 next = nvme_virt_to_bus(dev, prp_pool + page_size);
|
|
||||||
+ *(prp_pool + i) = cpu_to_le64(next);
|
|
||||||
i = 0;
|
|
||||||
prp_pool += page_size;
|
|
||||||
}
|
|
||||||
- *(prp_pool + i++) = cpu_to_le64((u64)buffer);
|
|
||||||
+ *(prp_pool + i++) = cpu_to_le64(nvme_virt_to_bus(dev, buffer));
|
|
||||||
buffer += page_size;
|
|
||||||
nprps--;
|
|
||||||
}
|
|
||||||
- *prp2 = (u64)dev->prp_pool;
|
|
||||||
+ *prp2 = nvme_virt_to_bus(dev, dev->prp_pool);
|
|
||||||
|
|
||||||
flush_dcache_range((ulong)dev->prp_pool, (ulong)dev->prp_pool +
|
|
||||||
dev->prp_entry_num * sizeof(u64));
|
|
||||||
@@ -356,6 +356,7 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev)
|
|
||||||
int result;
|
|
||||||
u32 aqa;
|
|
||||||
u64 cap = dev->cap;
|
|
||||||
+ u64 dma_addr;
|
|
||||||
struct nvme_queue *nvmeq;
|
|
||||||
/* most architectures use 4KB as the page size */
|
|
||||||
unsigned page_shift = 12;
|
|
||||||
@@ -396,8 +397,10 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev)
|
|
||||||
dev->ctrl_config |= NVME_CC_IOSQES | NVME_CC_IOCQES;
|
|
||||||
|
|
||||||
writel(aqa, &dev->bar->aqa);
|
|
||||||
- nvme_writeq((ulong)nvmeq->sq_cmds, &dev->bar->asq);
|
|
||||||
- nvme_writeq((ulong)nvmeq->cqes, &dev->bar->acq);
|
|
||||||
+ dma_addr = nvme_virt_to_bus(dev, nvmeq->sq_cmds);
|
|
||||||
+ nvme_writeq(dma_addr, &dev->bar->asq);
|
|
||||||
+ dma_addr = nvme_virt_to_bus(dev, nvmeq->cqes);
|
|
||||||
+ nvme_writeq(dma_addr, &dev->bar->acq);
|
|
||||||
|
|
||||||
result = nvme_enable_ctrl(dev);
|
|
||||||
if (result)
|
|
||||||
@@ -423,7 +426,7 @@ static int nvme_alloc_cq(struct nvme_dev *dev, u16 qid,
|
|
||||||
|
|
||||||
memset(&c, 0, sizeof(c));
|
|
||||||
c.create_cq.opcode = nvme_admin_create_cq;
|
|
||||||
- c.create_cq.prp1 = cpu_to_le64((ulong)nvmeq->cqes);
|
|
||||||
+ c.create_cq.prp1 = cpu_to_le64(nvme_virt_to_bus(dev, nvmeq->cqes));
|
|
||||||
c.create_cq.cqid = cpu_to_le16(qid);
|
|
||||||
c.create_cq.qsize = cpu_to_le16(nvmeq->q_depth - 1);
|
|
||||||
c.create_cq.cq_flags = cpu_to_le16(flags);
|
|
||||||
@@ -440,7 +443,7 @@ static int nvme_alloc_sq(struct nvme_dev *dev, u16 qid,
|
|
||||||
|
|
||||||
memset(&c, 0, sizeof(c));
|
|
||||||
c.create_sq.opcode = nvme_admin_create_sq;
|
|
||||||
- c.create_sq.prp1 = cpu_to_le64((ulong)nvmeq->sq_cmds);
|
|
||||||
+ c.create_sq.prp1 = cpu_to_le64(nvme_virt_to_bus(dev, nvmeq->sq_cmds));
|
|
||||||
c.create_sq.sqid = cpu_to_le16(qid);
|
|
||||||
c.create_sq.qsize = cpu_to_le16(nvmeq->q_depth - 1);
|
|
||||||
c.create_sq.sq_flags = cpu_to_le16(flags);
|
|
||||||
@@ -461,14 +464,14 @@ int nvme_identify(struct nvme_dev *dev, unsigned nsid,
|
|
||||||
memset(&c, 0, sizeof(c));
|
|
||||||
c.identify.opcode = nvme_admin_identify;
|
|
||||||
c.identify.nsid = cpu_to_le32(nsid);
|
|
||||||
- c.identify.prp1 = cpu_to_le64((u64)buffer);
|
|
||||||
+ c.identify.prp1 = cpu_to_le64(nvme_virt_to_bus(dev, buffer));
|
|
||||||
|
|
||||||
length -= (page_size - offset);
|
|
||||||
if (length <= 0) {
|
|
||||||
c.identify.prp2 = 0;
|
|
||||||
} else {
|
|
||||||
buffer += (page_size - offset);
|
|
||||||
- c.identify.prp2 = cpu_to_le64((u64)buffer);
|
|
||||||
+ c.identify.prp2 = cpu_to_le64(nvme_virt_to_bus(dev, buffer));
|
|
||||||
}
|
|
||||||
|
|
||||||
c.identify.cns = cpu_to_le32(cns);
|
|
||||||
@@ -493,7 +496,7 @@ int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid,
|
|
||||||
memset(&c, 0, sizeof(c));
|
|
||||||
c.features.opcode = nvme_admin_get_features;
|
|
||||||
c.features.nsid = cpu_to_le32(nsid);
|
|
||||||
- c.features.prp1 = cpu_to_le64((u64)buffer);
|
|
||||||
+ c.features.prp1 = cpu_to_le64(nvme_virt_to_bus(dev, buffer));
|
|
||||||
c.features.fid = cpu_to_le32(fid);
|
|
||||||
|
|
||||||
ret = nvme_submit_admin_cmd(dev, &c, result);
|
|
||||||
@@ -519,7 +522,7 @@ int nvme_set_features(struct nvme_dev *dev, unsigned fid, unsigned dword11,
|
|
||||||
|
|
||||||
memset(&c, 0, sizeof(c));
|
|
||||||
c.features.opcode = nvme_admin_set_features;
|
|
||||||
- c.features.prp1 = cpu_to_le64((u64)buffer);
|
|
||||||
+ c.features.prp1 = cpu_to_le64(nvme_virt_to_bus(dev, buffer));
|
|
||||||
c.features.fid = cpu_to_le32(fid);
|
|
||||||
c.features.dword11 = cpu_to_le32(dword11);
|
|
||||||
|
|
||||||
@@ -776,7 +779,7 @@ static ulong nvme_blk_rw(struct udevice *udev, lbaint_t blknr,
|
|
||||||
c.rw.slba = cpu_to_le64(slba);
|
|
||||||
slba += lbas;
|
|
||||||
c.rw.length = cpu_to_le16(lbas - 1);
|
|
||||||
- c.rw.prp1 = cpu_to_le64(temp_buffer);
|
|
||||||
+ c.rw.prp1 = cpu_to_le64(nvme_virt_to_bus(dev, temp_buffer));
|
|
||||||
c.rw.prp2 = cpu_to_le64(prp2);
|
|
||||||
status = nvme_submit_sync_cmd(dev->queues[NVME_IO_Q],
|
|
||||||
&c, NULL, IO_TIMEOUT);
|
|
||||||
@@ -835,6 +838,7 @@ static int nvme_probe(struct udevice *udev)
|
|
||||||
struct nvme_id_ns *id;
|
|
||||||
|
|
||||||
ndev->instance = trailing_strtol(udev->name);
|
|
||||||
+ ndev->dev = udev->parent;
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&ndev->namespaces);
|
|
||||||
ndev->bar = dm_pci_map_bar(udev, PCI_BASE_ADDRESS_0,
|
|
||||||
diff --git a/drivers/nvme/nvme.h b/drivers/nvme/nvme.h
|
|
||||||
index c6aae4da5d..31e6899bca 100644
|
|
||||||
--- a/drivers/nvme/nvme.h
|
|
||||||
+++ b/drivers/nvme/nvme.h
|
|
||||||
@@ -7,8 +7,15 @@
|
|
||||||
#ifndef __DRIVER_NVME_H__
|
|
||||||
#define __DRIVER_NVME_H__
|
|
||||||
|
|
||||||
+#include <phys2bus.h>
|
|
||||||
#include <asm/io.h>
|
|
||||||
|
|
||||||
+#if CONFIG_IS_ENABLED(DM_USB)
|
|
||||||
+#define nvme_to_dev(_dev) _dev->dev
|
|
||||||
+#else
|
|
||||||
+#define nvme_to_dev(_dev) NULL
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
struct nvme_id_power_state {
|
|
||||||
__le16 max_power; /* centiwatts */
|
|
||||||
__u8 rsvd2;
|
|
||||||
@@ -596,6 +603,9 @@ enum {
|
|
||||||
|
|
||||||
/* Represents an NVM Express device. Each nvme_dev is a PCI function. */
|
|
||||||
struct nvme_dev {
|
|
||||||
+#if CONFIG_IS_ENABLED(DM_USB)
|
|
||||||
+ struct udevice *dev;
|
|
||||||
+#endif
|
|
||||||
struct list_head node;
|
|
||||||
struct nvme_queue **queues;
|
|
||||||
u32 __iomem *dbs;
|
|
||||||
@@ -635,4 +645,9 @@ struct nvme_ns {
|
|
||||||
u8 flbas;
|
|
||||||
};
|
|
||||||
|
|
||||||
+static inline dma_addr_t nvme_virt_to_bus(struct nvme_dev *dev, void *addr)
|
|
||||||
+{
|
|
||||||
+ return dev_phys_to_bus(nvme_to_dev(dev), virt_to_phys(addr));
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
#endif /* __DRIVER_NVME_H__ */
|
|
||||||
--
|
|
||||||
2.36.0
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user