summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authornonaka <nonaka@NetBSD.org>2018-04-18 10:11:44 +0000
committernonaka <nonaka@NetBSD.org>2018-04-18 10:11:44 +0000
commit433840f4e26d94f82dcfba05df0355207709fbba (patch)
treee99481a7510143a84806b18472a5f774a1104a7d /sys/dev
parent447ace79c52e862b73e736baed7641706f143296 (diff)
nvmectl(8): Add big-endian support.
from FreeBSD nvmecontolr(8) r329824.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ic/ld_nvme.c8
-rw-r--r--sys/dev/ic/nvme.c39
-rw-r--r--sys/dev/ic/nvmeio.h104
3 files changed, 127 insertions, 24 deletions
diff --git a/sys/dev/ic/ld_nvme.c b/sys/dev/ic/ld_nvme.c
index 257bb72c60b..1ae85bb3aa3 100644
--- a/sys/dev/ic/ld_nvme.c
+++ b/sys/dev/ic/ld_nvme.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ld_nvme.c,v 1.19 2018/03/16 23:31:19 jdolecek Exp $ */
+/* $NetBSD: ld_nvme.c,v 1.20 2018/04/18 10:11:45 nonaka Exp $ */
/*-
* Copyright (C) 2016 NONAKA Kimihiro <nonaka@netbsd.org>
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ld_nvme.c,v 1.19 2018/03/16 23:31:19 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ld_nvme.c,v 1.20 2018/04/18 10:11:45 nonaka Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -86,7 +86,6 @@ ld_nvme_attach(device_t parent, device_t self, void *aux)
struct nvme_attach_args *naa = aux;
struct nvme_namespace *ns;
struct nvm_namespace_format *f;
- uint64_t nsze;
int error;
ld->sc_dv = self;
@@ -104,11 +103,10 @@ ld_nvme_attach(device_t parent, device_t self, void *aux)
ns = nvme_ns_get(sc->sc_nvme, sc->sc_nsid);
KASSERT(ns);
- nsze = lemtoh64(&ns->ident->nsze);
f = &ns->ident->lbaf[NVME_ID_NS_FLBAS(ns->ident->flbas)];
ld->sc_secsize = 1 << f->lbads;
- ld->sc_secperunit = nsze;
+ ld->sc_secperunit = ns->ident->nsze;
ld->sc_maxxfer = naa->naa_maxphys;
ld->sc_maxqueuecnt = naa->naa_qentries;
ld->sc_start = ld_nvme_start;
diff --git a/sys/dev/ic/nvme.c b/sys/dev/ic/nvme.c
index f634ddba40f..8ad414dba34 100644
--- a/sys/dev/ic/nvme.c
+++ b/sys/dev/ic/nvme.c
@@ -1,4 +1,4 @@
-/* $NetBSD: nvme.c,v 1.38 2018/04/18 10:05:59 nonaka Exp $ */
+/* $NetBSD: nvme.c,v 1.39 2018/04/18 10:11:45 nonaka Exp $ */
/* $OpenBSD: nvme.c,v 1.49 2016/04/18 05:59:50 dlg Exp $ */
/*
@@ -18,7 +18,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nvme.c,v 1.38 2018/04/18 10:05:59 nonaka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvme.c,v 1.39 2018/04/18 10:11:45 nonaka Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -624,7 +624,9 @@ nvme_ns_identify(struct nvme_softc *sc, uint16_t nsid)
identify = kmem_zalloc(sizeof(*identify), KM_SLEEP);
*identify = *((volatile struct nvm_identify_namespace *)NVME_DMA_KVA(mem));
- //memcpy(identify, NVME_DMA_KVA(mem), sizeof(*identify));
+
+ /* Convert data to host endian */
+ nvme_identify_namespace_swapbytes(identify);
ns = nvme_ns_get(sc, nsid);
KASSERT(ns);
@@ -899,7 +901,7 @@ nvme_getcache_fill(struct nvme_queue *q, struct nvme_ccb *ccb, void *slot)
struct nvme_sqe *sqe = slot;
sqe->opcode = NVM_ADMIN_GET_FEATURES;
- sqe->cdw10 = NVM_FEATURE_VOLATILE_WRITE_CACHE;
+ htolem32(&sqe->cdw10, NVM_FEATURE_VOLATILE_WRITE_CACHE);
}
static void
@@ -1122,7 +1124,7 @@ nvme_q_submit(struct nvme_softc *sc, struct nvme_queue *q, struct nvme_ccb *ccb,
sizeof(*sqe) * tail, sizeof(*sqe), BUS_DMASYNC_POSTWRITE);
memset(sqe, 0, sizeof(*sqe));
(*fill)(q, ccb, sqe);
- sqe->cid = ccb->ccb_id;
+ htolem16(&sqe->cid, ccb->ccb_id);
bus_dmamap_sync(sc->sc_dmat, NVME_DMA_MAP(q->q_sq_dmamem),
sizeof(*sqe) * tail, sizeof(*sqe), BUS_DMASYNC_PREWRITE);
@@ -1334,25 +1336,28 @@ nvme_identify(struct nvme_softc *sc, u_int mps)
goto done;
identify = NVME_DMA_KVA(mem);
-
- strnvisx(sn, sizeof(sn), (const char *)identify->sn,
- sizeof(identify->sn), VIS_TRIM|VIS_SAFE|VIS_OCTAL);
- strnvisx(mn, sizeof(mn), (const char *)identify->mn,
- sizeof(identify->mn), VIS_TRIM|VIS_SAFE|VIS_OCTAL);
- strnvisx(fr, sizeof(fr), (const char *)identify->fr,
- sizeof(identify->fr), VIS_TRIM|VIS_SAFE|VIS_OCTAL);
+ sc->sc_identify = *identify;
+ identify = NULL;
+
+ /* Convert data to host endian */
+ nvme_identify_controller_swapbytes(&sc->sc_identify);
+
+ strnvisx(sn, sizeof(sn), (const char *)sc->sc_identify.sn,
+ sizeof(sc->sc_identify.sn), VIS_TRIM|VIS_SAFE|VIS_OCTAL);
+ strnvisx(mn, sizeof(mn), (const char *)sc->sc_identify.mn,
+ sizeof(sc->sc_identify.mn), VIS_TRIM|VIS_SAFE|VIS_OCTAL);
+ strnvisx(fr, sizeof(fr), (const char *)sc->sc_identify.fr,
+ sizeof(sc->sc_identify.fr), VIS_TRIM|VIS_SAFE|VIS_OCTAL);
aprint_normal_dev(sc->sc_dev, "%s, firmware %s, serial %s\n", mn, fr,
sn);
- if (identify->mdts > 0) {
- mdts = (1 << identify->mdts) * (1 << mps);
+ if (sc->sc_identify.mdts > 0) {
+ mdts = (1 << sc->sc_identify.mdts) * (1 << mps);
if (mdts < sc->sc_mdts)
sc->sc_mdts = mdts;
}
- sc->sc_nn = lemtoh32(&identify->nn);
-
- memcpy(&sc->sc_identify, identify, sizeof(sc->sc_identify));
+ sc->sc_nn = sc->sc_identify.nn;
done:
nvme_dmamem_free(sc, mem);
diff --git a/sys/dev/ic/nvmeio.h b/sys/dev/ic/nvmeio.h
index dbfe8e9970f..52500543eca 100644
--- a/sys/dev/ic/nvmeio.h
+++ b/sys/dev/ic/nvmeio.h
@@ -1,4 +1,4 @@
-/* $NetBSD: nvmeio.h,v 1.1 2016/06/04 16:11:51 nonaka Exp $ */
+/* $NetBSD: nvmeio.h,v 1.2 2018/04/18 10:11:45 nonaka Exp $ */
/*-
* Copyright (C) 2012-2013 Intel Corporation
@@ -25,12 +25,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: head/sys/dev/nvme/nvme.h 296617 2016-03-10 17:13:10Z mav $
+ * $FreeBSD: head/sys/dev/nvme/nvme.h 329824 2018-02-22 13:32:31Z wma $
*/
#ifndef __NVMEIO_H__
#define __NVMEIO_H__
+#include <sys/endian.h>
#include <sys/ioccom.h>
#include <dev/ic/nvmereg.h>
@@ -94,4 +95,103 @@ struct nvme_pt_command {
uint32_t timeout;
};
+/* Endianess conversion functions for NVMe structs */
+static inline void
+nvme_le128toh(uint64_t v[2])
+{
+#if _BYTE_ORDER != _LITTLE_ENDIAN
+ uint64_t t;
+
+ t = le64toh(v[0]);
+ v[0] = le64toh(v[1]);
+ v[1] = t;
+#endif
+}
+
+static inline void
+nvme_namespace_format_swapbytes(struct nvm_namespace_format *format)
+{
+
+#if _BYTE_ORDER != _LITTLE_ENDIAN
+ format->ms = le16toh(format->ms);
+#endif
+}
+
+static inline void
+nvme_identify_namespace_swapbytes(struct nvm_identify_namespace *identify)
+{
+#if _BYTE_ORDER != _LITTLE_ENDIAN
+ u_int i;
+
+ identify->nsze = le64toh(identify->nsze);
+ identify->ncap = le64toh(identify->ncap);
+ identify->nuse = le64toh(identify->nuse);
+ identify->nawun = le16toh(identify->nawun);
+ identify->nawupf = le16toh(identify->nawupf);
+ identify->nacwu = le16toh(identify->nacwu);
+ identify->nabsn = le16toh(identify->nabsn);
+ identify->nabo = le16toh(identify->nabo);
+ identify->nabspf = le16toh(identify->nabspf);
+ identify->noiob = le16toh(identify->noiob);
+ for (i = 0; i < __arraycount(identify->lbaf); i++)
+ nvme_namespace_format_swapbytes(&identify->lbaf[i]);
+#endif
+}
+
+static inline void
+nvme_identify_psd_swapbytes(struct nvm_identify_psd *psd)
+{
+
+#if _BYTE_ORDER != _LITTLE_ENDIAN
+ psd->mp = le16toh(psd->mp);
+ psd->enlat = le32toh(psd->enlat);
+ psd->exlat = le32toh(psd->exlat);
+ psd->idlp = le16toh(psd->idlp);
+ psd->actp = le16toh(psd->actp);
+ psd->ap = le16toh(psd->ap);
+#endif
+}
+
+static inline void
+nvme_identify_controller_swapbytes(struct nvm_identify_controller *identify)
+{
+#if _BYTE_ORDER != _LITTLE_ENDIAN
+ u_int i;
+
+ identify->vid = le16toh(identify->vid);
+ identify->ssvid = le16toh(identify->ssvid);
+ identify->cntlid = le16toh(identify->cntlid);
+ identify->ver = le32toh(identify->ver);
+ identify->rtd3r = le32toh(identify->rtd3r);
+ identify->rtd3e = le32toh(identify->rtd3e);
+ identify->oaes = le32toh(identify->oaes);
+ identify->ctrattr = le32toh(identify->ctrattr);
+ identify->oacs = le16toh(identify->oacs);
+ identify->wctemp = le16toh(identify->wctemp);
+ identify->cctemp = le16toh(identify->cctemp);
+ identify->mtfa = le16toh(identify->mtfa);
+ identify->hmpre = le32toh(identify->hmpre);
+ identify->hmmin = le32toh(identify->hmmin);
+ nvme_le128toh(identify->untncap.tnvmcap);
+ nvme_le128toh(identify->untncap.unvmcap);
+ identify->rpmbs = le32toh(identify->rpmbs);
+ identify->edstt = le16toh(identify->edstt);
+ identify->kas = le16toh(identify->kas);
+ identify->hctma = le16toh(identify->hctma);
+ identify->mntmt = le16toh(identify->mntmt);
+ identify->mxtmt = le16toh(identify->mxtmt);
+ identify->sanicap = le32toh(identify->sanicap);
+ identify->maxcmd = le16toh(identify->maxcmd);
+ identify->nn = le32toh(identify->nn);
+ identify->oncs = le16toh(identify->oncs);
+ identify->fuses = le16toh(identify->fuses);
+ identify->awun = le16toh(identify->awun);
+ identify->awupf = le16toh(identify->awupf);
+ identify->acwu = le16toh(identify->acwu);
+ identify->sgls = le32toh(identify->sgls);
+ for (i = 0; i < __arraycount(identify->psd); i++)
+ nvme_identify_psd_swapbytes(&identify->psd[i]);
+#endif
+}
+
#endif /* __NVMEIO_H__ */