Skip to content

Instantly share code, notes, and snippets.

@nonakap
Last active May 14, 2021 01:03
Show Gist options
  • Save nonakap/8f17e4210bf985a181d9d8749ed6a820 to your computer and use it in GitHub Desktop.
Save nonakap/8f17e4210bf985a181d9d8749ed6a820 to your computer and use it in GitHub Desktop.
Fix NetBSD PR/55189
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