Last active
May 14, 2021 01:03
-
-
Save nonakap/8f17e4210bf985a181d9d8749ed6a820 to your computer and use it in GitHub Desktop.
Fix NetBSD PR/55189
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/sys/dev/ic/nvme.c b/sys/dev/ic/nvme.c | |
index f371baeb0a0..76445d3fe9e 100644 | |
--- a/sys/dev/ic/nvme.c | |
+++ b/sys/dev/ic/nvme.c | |
@@ -564,10 +564,33 @@ nvme_detach(struct nvme_softc *sc, int flags) | |
return 0; | |
} | |
+bool | |
+nvme_set_shutdown_reason(struct nvme_softc *sc, int how __unused) | |
+{ | |
+ uint32_t cc, csts; | |
+ int i; | |
+ | |
+ cc = nvme_read4(sc, NVME_CC); | |
+ CLR(cc, NVME_CC_SHN_MASK); | |
+ SET(cc, NVME_CC_SHN(NVME_CC_SHN_NORMAL)); | |
+ nvme_write4(sc, NVME_CC, cc); | |
+ | |
+ for (i = 0; i < 4000; i++) { | |
+ nvme_barrier(sc, 0, sc->sc_ios, | |
+ BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); | |
+ csts = nvme_read4(sc, NVME_CSTS); | |
+ if ((csts & NVME_CSTS_SHST_MASK) == NVME_CSTS_SHST_DONE) | |
+ return true; | |
+ | |
+ delay(1000); | |
+ } | |
+ | |
+ return false; | |
+} | |
+ | |
static int | |
nvme_shutdown(struct nvme_softc *sc) | |
{ | |
- uint32_t cc, csts; | |
bool disabled = false; | |
int i; | |
@@ -585,20 +608,8 @@ nvme_shutdown(struct nvme_softc *sc) | |
if (disabled) | |
goto disable; | |
- cc = nvme_read4(sc, NVME_CC); | |
- CLR(cc, NVME_CC_SHN_MASK); | |
- SET(cc, NVME_CC_SHN(NVME_CC_SHN_NORMAL)); | |
- nvme_write4(sc, NVME_CC, cc); | |
- | |
- for (i = 0; i < 4000; i++) { | |
- nvme_barrier(sc, 0, sc->sc_ios, | |
- BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); | |
- csts = nvme_read4(sc, NVME_CSTS); | |
- if ((csts & NVME_CSTS_SHST_MASK) == NVME_CSTS_SHST_DONE) | |
- return 0; | |
- | |
- delay(1000); | |
- } | |
+ if (nvme_set_shutdown_reason(sc, 0)) | |
+ return 0; | |
aprint_error_dev(sc->sc_dev, "unable to shudown, disabling\n"); | |
diff --git a/sys/dev/ic/nvmevar.h b/sys/dev/ic/nvmevar.h | |
index abec63e96cd..84b3ba1ed4c 100644 | |
--- a/sys/dev/ic/nvmevar.h | |
+++ b/sys/dev/ic/nvmevar.h | |
@@ -167,6 +167,7 @@ int nvme_intr(void *); | |
void nvme_softintr_intx(void *); | |
int nvme_intr_msi(void *); | |
void nvme_softintr_msi(void *); | |
+bool nvme_set_shutdown_reason(struct nvme_softc *, int); | |
static __inline struct nvme_queue * | |
nvme_get_q(struct nvme_softc *sc, struct buf *bp, bool waitok) | |
diff --git a/sys/dev/pci/nvme_pci.c b/sys/dev/pci/nvme_pci.c | |
index d34649fdb2f..d3a0b0c2afc 100644 | |
--- a/sys/dev/pci/nvme_pci.c | |
+++ b/sys/dev/pci/nvme_pci.c | |
@@ -81,6 +81,7 @@ struct nvme_pci_softc { | |
static int nvme_pci_match(device_t, cfdata_t, void *); | |
static void nvme_pci_attach(device_t, device_t, void *); | |
static int nvme_pci_detach(device_t, int); | |
+static bool nvme_pci_shutdown(device_t, int); | |
static int nvme_pci_rescan(device_t, const char *, const int *); | |
CFATTACH_DECL3_NEW(nvme_pci, sizeof(struct nvme_pci_softc), | |
@@ -232,7 +233,7 @@ nvme_pci_attach(device_t parent, device_t self, void *aux) | |
goto softintr_free; | |
} | |
- if (!pmf_device_register(self, NULL, NULL)) | |
+ if (!pmf_device_register1(self, NULL, NULL, nvme_pci_shutdown)) | |
aprint_error_dev(self, "couldn't establish power handler\n"); | |
SET(sc->sc_flags, NVME_F_ATTACHED); | |
@@ -279,6 +280,18 @@ nvme_pci_detach(device_t self, int flags) | |
return 0; | |
} | |
+static bool | |
+nvme_pci_shutdown(device_t self, int how) | |
+{ | |
+ struct nvme_pci_softc *psc = device_private(self); | |
+ struct nvme_softc *sc = &psc->psc_nvme; | |
+ | |
+ if (!ISSET(sc->sc_flags, NVME_F_ATTACHED)) | |
+ return true; | |
+ | |
+ return nvme_set_shutdown_reason(sc, how); | |
+} | |
+ | |
static int | |
nvme_pci_intr_establish(struct nvme_softc *sc, uint16_t qid, | |
struct nvme_queue *q) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment