summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2016-04-14 06:16:37 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2016-04-14 06:16:37 +0000
commita0b540d69080af27151bd71cae27eb803b6b313c (patch)
tree5b676f60ee9355c8f109976fe445246d9a00cf05
parent3f2c4fdcf79b4fc12ee25a5f0d632511055f5f06 (diff)
allocate dma memory for ccbs to use as prpe lists
prpe is short for Physical Region Page Entry. this is where long lists of dma regions go when they wont fit into a submission queue entry.
-rw-r--r--sys/dev/ic/nvme.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/sys/dev/ic/nvme.c b/sys/dev/ic/nvme.c
index 184c3cbb5ab..ebb282f62a6 100644
--- a/sys/dev/ic/nvme.c
+++ b/sys/dev/ic/nvme.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nvme.c,v 1.39 2016/04/14 06:10:49 dlg Exp $ */
+/* $OpenBSD: nvme.c,v 1.40 2016/04/14 06:16:36 dlg Exp $ */
/*
* Copyright (c) 2014 David Gwynne <dlg@openbsd.org>
@@ -963,6 +963,8 @@ int
nvme_ccbs_alloc(struct nvme_softc *sc, u_int nccbs)
{
struct nvme_ccb *ccb;
+ bus_addr_t off;
+ u_int64_t *prpl;
u_int i;
sc->sc_ccbs = mallocarray(nccbs, sizeof(*ccb), M_DEVBUF,
@@ -970,16 +972,30 @@ nvme_ccbs_alloc(struct nvme_softc *sc, u_int nccbs)
if (sc->sc_ccbs == NULL)
return (1);
+ sc->sc_ccb_prpls = nvme_dmamem_alloc(sc,
+ sizeof(*prpl) * sc->sc_max_sgl * nccbs);
+
+ prpl = NVME_DMA_KVA(sc->sc_ccb_prpls);
+ off = 0;
+
for (i = 0; i < nccbs; i++) {
ccb = &sc->sc_ccbs[i];
- if (bus_dmamap_create(sc->sc_dmat, sc->sc_mdts, sc->sc_max_sgl,
+ if (bus_dmamap_create(sc->sc_dmat, sc->sc_mdts,
+ sc->sc_max_sgl + 1 /* we get a free prp in the sqe */,
sc->sc_mps, sc->sc_mps, BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW,
&ccb->ccb_dmamap) != 0)
goto free_maps;
ccb->ccb_id = i;
+ ccb->ccb_prpl = prpl;
+ ccb->ccb_prpl_off = off;
+ ccb->ccb_prpl_dva = NVME_DMA_DVA(sc->sc_ccb_prpls) + off;
+
SIMPLEQ_INSERT_TAIL(&sc->sc_ccb_list, ccb, ccb_entry);
+
+ prpl += sc->sc_max_sgl;
+ off += sizeof(*prpl) * sc->sc_max_sgl;
}
return (0);
@@ -1025,6 +1041,7 @@ nvme_ccbs_free(struct nvme_softc *sc)
bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap);
}
+ nvme_dmamem_free(sc, sc->sc_ccb_prpls);
free(sc->sc_ccbs, M_DEVBUF, 0);
}