diff --git a/sys/dev/nvme/nvme.c b/sys/dev/nvme/nvme.c index 9db2b14d13d0..8196ff78c854 100644 --- a/sys/dev/nvme/nvme.c +++ b/sys/dev/nvme/nvme.c @@ -327,8 +327,10 @@ nvme_notify(struct nvme_consumer *cons, */ return; } - for (ns_idx = 0; ns_idx < ctrlr->cdata.nn; ns_idx++) { + for (ns_idx = 0; ns_idx < min(ctrlr->cdata.nn, NVME_MAX_NAMESPACES); ns_idx++) { ns = &ctrlr->ns[ns_idx]; + if (ns->data.nsze == 0) + continue; if (cons->ns_fn != NULL) ns->cons_cookie[cons->id] = (*cons->ns_fn)(ns, ctrlr_cookie); diff --git a/sys/dev/nvme/nvme_ctrlr.c b/sys/dev/nvme/nvme_ctrlr.c index fd836f991090..c3a818f3d637 100644 --- a/sys/dev/nvme/nvme_ctrlr.c +++ b/sys/dev/nvme/nvme_ctrlr.c @@ -458,13 +458,11 @@ static int nvme_ctrlr_construct_namespaces(struct nvme_controller *ctrlr) { struct nvme_namespace *ns; - int i, status; + int i; - for (i = 0; i < ctrlr->cdata.nn; i++) { + for (i = 0; i < min(ctrlr->cdata.nn, NVME_MAX_NAMESPACES); i++) { ns = &ctrlr->ns[i]; - status = nvme_ns_construct(ns, i+1, ctrlr); - if (status != 0) - return (status); + nvme_ns_construct(ns, i+1, ctrlr); } return (0); diff --git a/sys/dev/nvme/nvme_ns.c b/sys/dev/nvme/nvme_ns.c index 754d074c4937..80364b4a0793 100644 --- a/sys/dev/nvme/nvme_ns.c +++ b/sys/dev/nvme/nvme_ns.c @@ -511,6 +511,15 @@ nvme_ns_construct(struct nvme_namespace *ns, uint16_t id, return (ENXIO); } + /* + * If the size of is zero, chances are this isn't a valid + * namespace (eg one that's not been configured yet). The + * standard says the entire id will be zeros, so this is a + * cheap way to test for that. + */ + if (ns->data.nsze == 0) + return (ENXIO); + /* * Note: format is a 0-based value, so > is appropriate here, * not >=. @@ -518,7 +527,7 @@ nvme_ns_construct(struct nvme_namespace *ns, uint16_t id, if (ns->data.flbas.format > ns->data.nlbaf) { printf("lba format %d exceeds number supported (%d)\n", ns->data.flbas.format, ns->data.nlbaf+1); - return (1); + return (ENXIO); } if (ctrlr->cdata.oncs.dsm)