summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/nvme/nvme_ctrlr.c10
-rw-r--r--sys/dev/nvme/nvme_private.h3
2 files changed, 13 insertions, 0 deletions
diff --git a/sys/dev/nvme/nvme_ctrlr.c b/sys/dev/nvme/nvme_ctrlr.c
index c4ec259..20115c6 100644
--- a/sys/dev/nvme/nvme_ctrlr.c
+++ b/sys/dev/nvme/nvme_ctrlr.c
@@ -457,6 +457,14 @@ nvme_ctrlr_identify(struct nvme_controller *ctrlr)
nvme_chatham_populate_cdata(ctrlr);
#endif
+ /*
+ * Use MDTS to ensure our default max_xfer_size doesn't exceed what the
+ * controller supports.
+ */
+ if (ctrlr->cdata.mdts > 0)
+ ctrlr->max_xfer_size = min(ctrlr->max_xfer_size,
+ ctrlr->min_page_size * (1 << (ctrlr->cdata.mdts)));
+
return (0);
}
@@ -923,6 +931,8 @@ nvme_ctrlr_construct(struct nvme_controller *ctrlr, device_t dev)
if (cap_hi.bits.dstrd != 0)
return (ENXIO);
+ ctrlr->min_page_size = 1 << (12 + cap_hi.bits.mpsmin);
+
/* Get ready timeout value from controller, in units of 500ms. */
cap_lo.raw = nvme_mmio_read_4(ctrlr, cap_lo);
ctrlr->ready_timeout_in_ms = cap_lo.bits.to * 500;
diff --git a/sys/dev/nvme/nvme_private.h b/sys/dev/nvme/nvme_private.h
index dd36a86..4a02a1b 100644
--- a/sys/dev/nvme/nvme_private.h
+++ b/sys/dev/nvme/nvme_private.h
@@ -265,6 +265,9 @@ struct nvme_controller {
/** maximum i/o size in bytes */
uint32_t max_xfer_size;
+ /** minimum page size supported by this controller in bytes */
+ uint32_t min_page_size;
+
/** interrupt coalescing time period (in microseconds) */
uint32_t int_coal_time;
OpenPOWER on IntegriCloud