diff --git a/sys/dev/nvme/nvme.c b/sys/dev/nvme/nvme.c index 175e78336b39..022c6643bbe4 100644 --- a/sys/dev/nvme/nvme.c +++ b/sys/dev/nvme/nvme.c @@ -330,16 +330,21 @@ nvme_notify(struct nvme_consumer *cons, return; cmpset = atomic_cmpset_32(&ctrlr->notification_sent, 0, 1); - if (cmpset == 0) return; if (cons->ctrlr_fn != NULL) ctrlr_cookie = (*cons->ctrlr_fn)(ctrlr); else - ctrlr_cookie = NULL; + ctrlr_cookie = (void *)(uintptr_t)0xdeadc0dedeadc0de; ctrlr->cons_cookie[cons->id] = ctrlr_cookie; + + /* ctrlr_fn has failed. Nothing to notify here any more. */ + if (ctrlr_cookie == NULL) + return; + if (ctrlr->is_failed) { + ctrlr->cons_cookie[cons->id] = NULL; if (cons->fail_fn != NULL) (*cons->fail_fn)(ctrlr_cookie); /* @@ -395,13 +400,16 @@ nvme_notify_async_consumers(struct nvme_controller *ctrlr, uint32_t log_page_size) { struct nvme_consumer *cons; + void *ctrlr_cookie; uint32_t i; for (i = 0; i < NVME_MAX_CONSUMERS; i++) { cons = &nvme_consumer[i]; - if (cons->id != INVALID_CONSUMER_ID && cons->async_fn != NULL) - (*cons->async_fn)(ctrlr->cons_cookie[i], async_cpl, + if (cons->id != INVALID_CONSUMER_ID && cons->async_fn != NULL && + (ctrlr_cookie = ctrlr->cons_cookie[i]) != NULL) { + (*cons->async_fn)(ctrlr_cookie, async_cpl, log_page_id, log_page_buffer, log_page_size); + } } } @@ -409,6 +417,7 @@ void nvme_notify_fail_consumers(struct nvme_controller *ctrlr) { struct nvme_consumer *cons; + void *ctrlr_cookie; uint32_t i; /* @@ -422,8 +431,12 @@ nvme_notify_fail_consumers(struct nvme_controller *ctrlr) for (i = 0; i < NVME_MAX_CONSUMERS; i++) { cons = &nvme_consumer[i]; - if (cons->id != INVALID_CONSUMER_ID && cons->fail_fn != NULL) - cons->fail_fn(ctrlr->cons_cookie[i]); + if (cons->id != INVALID_CONSUMER_ID && + (ctrlr_cookie = ctrlr->cons_cookie[i]) != NULL) { + ctrlr->cons_cookie[i] = NULL; + if (cons->fail_fn != NULL) + cons->fail_fn(ctrlr_cookie); + } } } @@ -432,6 +445,7 @@ nvme_notify_ns(struct nvme_controller *ctrlr, int nsid) { struct nvme_consumer *cons; struct nvme_namespace *ns = &ctrlr->ns[nsid - 1]; + void *ctrlr_cookie; uint32_t i; if (!ctrlr->is_initialized) @@ -439,9 +453,9 @@ nvme_notify_ns(struct nvme_controller *ctrlr, int nsid) for (i = 0; i < NVME_MAX_CONSUMERS; i++) { cons = &nvme_consumer[i]; - if (cons->id != INVALID_CONSUMER_ID && cons->ns_fn != NULL) - ns->cons_cookie[cons->id] = - (*cons->ns_fn)(ns, ctrlr->cons_cookie[cons->id]); + if (cons->id != INVALID_CONSUMER_ID && cons->ns_fn != NULL && + (ctrlr_cookie = ctrlr->cons_cookie[i]) != NULL) + ns->cons_cookie[i] = (*cons->ns_fn)(ns, ctrlr_cookie); } }