diff --git a/sys/dev/nvme/nvme_ctrlr.c b/sys/dev/nvme/nvme_ctrlr.c index c4ec259918e1..20115c6c065a 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 dd36a86473ba..4a02a1b443f7 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;