aboutsummaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2020-11-29 00:20:31 +0000
committerAlexander Motin <mav@FreeBSD.org>2020-11-29 00:20:31 +0000
commitac90f70d1ec717a070d3370096f499daf3eef1ce (patch)
tree8b9fb342667c8f939e03cbf55545bafa9e569eba /sys/dev
parentfd26389be7e149849c75a10311805a29d7215918 (diff)
Notes
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/nvme/nvme.h4
-rw-r--r--sys/dev/nvme/nvme_ctrlr.c11
-rw-r--r--sys/dev/nvme/nvme_private.h9
-rw-r--r--sys/dev/nvme/nvme_qpair.c11
4 files changed, 16 insertions, 19 deletions
diff --git a/sys/dev/nvme/nvme.h b/sys/dev/nvme/nvme.h
index a2aaed355b15..9ec3b4236511 100644
--- a/sys/dev/nvme/nvme.h
+++ b/sys/dev/nvme/nvme.h
@@ -59,8 +59,8 @@
*/
#define NVME_GLOBAL_NAMESPACE_TAG ((uint32_t)0xFFFFFFFF)
-/* Cap nvme to 1MB transfers driver explodes with larger sizes */
-#define NVME_MAX_XFER_SIZE (maxphys < (1<<20) ? maxphys : (1<<20))
+/* Cap transfers by the maximum addressable by page-sized PRP (4KB -> 2MB). */
+#define NVME_MAX_XFER_SIZE MIN(maxphys, (PAGE_SIZE/8*PAGE_SIZE))
/* Register field definitions */
#define NVME_CAP_LO_REG_MQES_SHIFT (0)
diff --git a/sys/dev/nvme/nvme_ctrlr.c b/sys/dev/nvme/nvme_ctrlr.c
index 32756afa0a1e..b3276e4e0fb4 100644
--- a/sys/dev/nvme/nvme_ctrlr.c
+++ b/sys/dev/nvme/nvme_ctrlr.c
@@ -1053,16 +1053,16 @@ nvme_ctrlr_start(void *ctrlr_arg, bool resetting)
* the number of I/O queues supported, so cannot reset
* the adminq again here.
*/
- if (resetting)
+ if (resetting) {
nvme_qpair_reset(&ctrlr->adminq);
+ nvme_admin_qpair_enable(&ctrlr->adminq);
+ }
if (ctrlr->ioq != NULL) {
for (i = 0; i < ctrlr->num_io_queues; i++)
nvme_qpair_reset(&ctrlr->ioq[i]);
}
- nvme_admin_qpair_enable(&ctrlr->adminq);
-
/*
* If it was a reset on initialization command timeout, just
* return here, letting initialization code fail gracefully.
@@ -1070,7 +1070,7 @@ nvme_ctrlr_start(void *ctrlr_arg, bool resetting)
if (resetting && !ctrlr->is_initialized)
return;
- if (nvme_ctrlr_identify(ctrlr) != 0) {
+ if (resetting && nvme_ctrlr_identify(ctrlr) != 0) {
nvme_ctrlr_fail(ctrlr);
return;
}
@@ -1145,7 +1145,8 @@ fail:
nvme_qpair_reset(&ctrlr->adminq);
nvme_admin_qpair_enable(&ctrlr->adminq);
- if (nvme_ctrlr_set_num_qpairs(ctrlr) == 0 &&
+ if (nvme_ctrlr_identify(ctrlr) == 0 &&
+ nvme_ctrlr_set_num_qpairs(ctrlr) == 0 &&
nvme_ctrlr_construct_io_qpairs(ctrlr) == 0)
nvme_ctrlr_start(ctrlr, false);
else
diff --git a/sys/dev/nvme/nvme_private.h b/sys/dev/nvme/nvme_private.h
index 3433f5b47eb2..d44f1989dd71 100644
--- a/sys/dev/nvme/nvme_private.h
+++ b/sys/dev/nvme/nvme_private.h
@@ -56,15 +56,6 @@ MALLOC_DECLARE(M_NVME);
#define IDT32_PCI_ID 0x80d0111d /* 32 channel board */
#define IDT8_PCI_ID 0x80d2111d /* 8 channel board */
-/*
- * For commands requiring more than 2 PRP entries, one PRP will be
- * embedded in the command (prp1), and the rest of the PRP entries
- * will be in a list pointed to by the command (prp2). This means
- * that real max number of PRP entries we support is 32+1, which
- * results in a max xfer size of 32*PAGE_SIZE.
- */
-#define NVME_MAX_PRP_LIST_ENTRIES (NVME_MAX_XFER_SIZE / PAGE_SIZE)
-
#define NVME_ADMIN_TRACKERS (16)
#define NVME_ADMIN_ENTRIES (128)
/* min and max are defined in admin queue attributes section of spec */
diff --git a/sys/dev/nvme/nvme_qpair.c b/sys/dev/nvme/nvme_qpair.c
index 850a4ba19760..1fd1f9513cb3 100644
--- a/sys/dev/nvme/nvme_qpair.c
+++ b/sys/dev/nvme/nvme_qpair.c
@@ -687,8 +687,8 @@ nvme_qpair_construct(struct nvme_qpair *qpair,
/* Note: NVMe PRP format is restricted to 4-byte alignment. */
err = bus_dma_tag_create(bus_get_dma_tag(ctrlr->dev),
4, PAGE_SIZE, BUS_SPACE_MAXADDR,
- BUS_SPACE_MAXADDR, NULL, NULL, NVME_MAX_XFER_SIZE,
- (NVME_MAX_XFER_SIZE/PAGE_SIZE)+1, PAGE_SIZE, 0,
+ BUS_SPACE_MAXADDR, NULL, NULL, ctrlr->max_xfer_size,
+ btoc(ctrlr->max_xfer_size) + 1, PAGE_SIZE, 0,
NULL, NULL, &qpair->dma_tag_payload);
if (err != 0) {
nvme_printf(ctrlr, "payload tag create failed %d\n", err);
@@ -703,7 +703,12 @@ nvme_qpair_construct(struct nvme_qpair *qpair,
cmdsz = roundup2(cmdsz, PAGE_SIZE);
cplsz = qpair->num_entries * sizeof(struct nvme_completion);
cplsz = roundup2(cplsz, PAGE_SIZE);
- prpsz = sizeof(uint64_t) * NVME_MAX_PRP_LIST_ENTRIES;
+ /*
+ * For commands requiring more than 2 PRP entries, one PRP will be
+ * embedded in the command (prp1), and the rest of the PRP entries
+ * will be in a list pointed to by the command (prp2).
+ */
+ prpsz = sizeof(uint64_t) * btoc(ctrlr->max_xfer_size);
prpmemsz = qpair->num_trackers * prpsz;
allocsz = cmdsz + cplsz + prpmemsz;