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 <marcan@marcan.st>
This commit is contained in:
Hector Martin 2023-04-10 03:06:17 +09:00
parent 7d37a61a06
commit 9a2e530fed
3 changed files with 53 additions and 2 deletions

View file

@ -52,7 +52,7 @@ asc_dev_t *asc_init(const char *path)
asc->cpu_base = base; asc->cpu_base = base;
asc->base = base + 0x8000; asc->base = base + 0x8000;
clear32(base + ASC_CPU_CONTROL, ASC_CPU_CONTROL_START); // clear32(base + ASC_CPU_CONTROL, ASC_CPU_CONTROL_START);
return asc; 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); 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) bool asc_can_recv(asc_dev_t *asc)
{ {
return !(read32(asc->base + ASC_MBOX_I2A_CONTROL) & ASC_MBOX_CONTROL_EMPTY); return !(read32(asc->base + ASC_MBOX_I2A_CONTROL) & ASC_MBOX_CONTROL_EMPTY);

View file

@ -19,6 +19,7 @@ int asc_get_iop_node(asc_dev_t *asc);
void asc_cpu_start(asc_dev_t *asc); void asc_cpu_start(asc_dev_t *asc);
void asc_cpu_stop(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_recv(asc_dev_t *asc);
bool asc_can_send(asc_dev_t *asc); bool asc_can_send(asc_dev_t *asc);

View file

@ -427,10 +427,55 @@ out_adminq:
return false; 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) void nvme_shutdown(void)
{ {
if (!nvme_initialized) { if (!nvme_initialized) {
printf("nvme: trying to shut down but not initialized\n"); // nvme_ensure_shutdown();
return; return;
} }