From 9a2e530fed922b44ad65a991e3b410dbc87116b7 Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Mon, 10 Apr 2023 03:06:17 +0900 Subject: [PATCH] nvme: Add nvme_ensure_shutdown() We're not using it in the end because we fixed this in Linux, but I went through the trouble of writing the function so we might as well leave it lying around. Signed-off-by: Hector Martin --- src/asc.c | 7 ++++++- src/asc.h | 1 + src/nvme.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/asc.c b/src/asc.c index 67c9d46a..2212a28d 100644 --- a/src/asc.c +++ b/src/asc.c @@ -52,7 +52,7 @@ asc_dev_t *asc_init(const char *path) asc->cpu_base = base; asc->base = base + 0x8000; - clear32(base + ASC_CPU_CONTROL, ASC_CPU_CONTROL_START); + // clear32(base + ASC_CPU_CONTROL, ASC_CPU_CONTROL_START); return asc; } @@ -76,6 +76,11 @@ void asc_cpu_stop(asc_dev_t *asc) clear32(asc->cpu_base + ASC_CPU_CONTROL, ASC_CPU_CONTROL_START); } +bool asc_cpu_running(asc_dev_t *asc) +{ + return read32(asc->cpu_base + ASC_CPU_CONTROL) & ASC_CPU_CONTROL_START; +} + bool asc_can_recv(asc_dev_t *asc) { return !(read32(asc->base + ASC_MBOX_I2A_CONTROL) & ASC_MBOX_CONTROL_EMPTY); diff --git a/src/asc.h b/src/asc.h index 0aac349e..8a7ee3c3 100644 --- a/src/asc.h +++ b/src/asc.h @@ -19,6 +19,7 @@ int asc_get_iop_node(asc_dev_t *asc); void asc_cpu_start(asc_dev_t *asc); void asc_cpu_stop(asc_dev_t *asc); +bool asc_cpu_running(asc_dev_t *asc); bool asc_can_recv(asc_dev_t *asc); bool asc_can_send(asc_dev_t *asc); diff --git a/src/nvme.c b/src/nvme.c index 2c7b93f0..e40df4db 100644 --- a/src/nvme.c +++ b/src/nvme.c @@ -427,10 +427,55 @@ out_adminq: return false; } +void nvme_ensure_shutdown(void) +{ + nvme_asc = asc_init("/arm-io/ans"); + if (!nvme_asc) + return; + + if (!asc_cpu_running(nvme_asc)) { + printf("nvme: ANS not running\n"); + asc_free(nvme_asc); + nvme_asc = NULL; + return; + } + + printf("nvme: Found ANS left powered, doing a proper shutdown\n"); + + nvme_sart = sart_init("/arm-io/sart-ans"); + if (!nvme_sart) + goto fail; + + nvme_rtkit = rtkit_init("nvme", nvme_asc, NULL, NULL, nvme_sart); + if (!nvme_rtkit) + goto fail; + + if (!rtkit_boot(nvme_rtkit)) + goto fail; + + rtkit_sleep(nvme_rtkit); + +fail: + if (nvme_rtkit) { + rtkit_free(nvme_rtkit); + nvme_rtkit = NULL; + } + if (nvme_sart) { + sart_free(nvme_sart); + nvme_sart = NULL; + } + asc_free(nvme_asc); + nvme_asc = NULL; + + // Some machines call this ANS, some ANS2... + pmgr_reset(nvme_die, "ANS"); + pmgr_reset(nvme_die, "ANS2"); +} + void nvme_shutdown(void) { if (!nvme_initialized) { - printf("nvme: trying to shut down but not initialized\n"); + // nvme_ensure_shutdown(); return; }