diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/ic/nvme.c | 65 | ||||
-rw-r--r-- | sys/dev/ic/nvmereg.h | 34 |
2 files changed, 64 insertions, 35 deletions
diff --git a/sys/dev/ic/nvme.c b/sys/dev/ic/nvme.c index eb99e3276af..740b41ca62a 100644 --- a/sys/dev/ic/nvme.c +++ b/sys/dev/ic/nvme.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nvme.c,v 1.2 2014/04/15 10:28:07 dlg Exp $ */ +/* $OpenBSD: nvme.c,v 1.3 2014/04/16 00:26:59 dlg Exp $ */ /* * Copyright (c) 2014 David Gwynne <dlg@openbsd.org> @@ -49,8 +49,6 @@ void nvme_dumpregs(struct nvme_softc *); int nvme_identify(struct nvme_softc *); void nvme_fill_identify(struct nvme_softc *, struct nvme_ccb *, void *); -void nvme_identify_done(struct nvme_softc *, - struct nvme_ccb *, struct nvme_cqe *); int nvme_ccbs_alloc(struct nvme_softc *, u_int); void nvme_ccbs_free(struct nvme_softc *); @@ -66,6 +64,8 @@ void nvme_poll_fill(struct nvme_softc *, struct nvme_ccb *, void *); void nvme_poll_done(struct nvme_softc *, struct nvme_ccb *, struct nvme_cqe *); +void nvme_empty_done(struct nvme_softc *, + struct nvme_ccb *, struct nvme_cqe *); struct nvme_queue * nvme_q_alloc(struct nvme_softc *, u_int, u_int, u_int); @@ -354,6 +354,7 @@ nvme_poll(struct nvme_softc *sc, struct nvme_queue *q, struct nvme_ccb *ccb, struct nvme_poll_state state; void (*done)(struct nvme_softc *, struct nvme_ccb *, struct nvme_cqe *); void *cookie; + u_int16_t flags; memset(&state, 0, sizeof(state)); state.s.cid = ccb->ccb_id; @@ -376,7 +377,9 @@ nvme_poll(struct nvme_softc *sc, struct nvme_queue *q, struct nvme_ccb *ccb, ccb->ccb_cookie = cookie; done(sc, ccb, &state.c); - return (0); + flags = lemtoh16(&state.c.flags); + + return (NVME_CQE_SCT(flags) | NVME_CQE_SC(flags)); } void @@ -398,6 +401,12 @@ nvme_poll_done(struct nvme_softc *sc, struct nvme_ccb *ccb, state->c = *cqe; } +void +nvme_empty_done(struct nvme_softc *sc, struct nvme_ccb *ccb, + struct nvme_cqe *cqe) +{ +} + int nvme_q_complete(struct nvme_softc *sc, struct nvme_queue *q) { @@ -438,23 +447,41 @@ nvme_q_complete(struct nvme_softc *sc, struct nvme_queue *q) int nvme_identify(struct nvme_softc *sc) { - struct nvme_ccb *ccb; + char sn[41], mn[81], fr[17]; + struct nvm_identify_controller *identify; struct nvme_dmamem *mem; + struct nvme_ccb *ccb; int rv = 1; ccb = nvme_ccb_get(sc); if (ccb == NULL) panic("nvme_identify: nvme_ccb_get returned NULL"); - mem = nvme_dmamem_alloc(sc, sizeof(struct nvm_identify_controller)); + mem = nvme_dmamem_alloc(sc, sizeof(*identify)); if (mem == NULL) return (1); - ccb->ccb_done = nvme_identify_done; + identify = NVME_DMA_KVA(mem); + + ccb->ccb_done = nvme_empty_done; ccb->ccb_cookie = mem; + bus_dmamap_sync(sc->sc_dmat, NVME_DMA_MAP(mem), + 0, sizeof(*identify), BUS_DMASYNC_PREREAD); rv = nvme_poll(sc, sc->sc_admin_q, ccb, nvme_fill_identify); + bus_dmamap_sync(sc->sc_dmat, NVME_DMA_MAP(mem), + 0, sizeof(*identify), BUS_DMASYNC_POSTREAD); + if (rv != 0) + goto done; + + scsi_strvis(sn, identify->sn, sizeof(identify->sn)); + scsi_strvis(mn, identify->mn, sizeof(identify->mn)); + scsi_strvis(fr, identify->fr, sizeof(identify->fr)); + + printf("%s: %s, firmware %s, serial %s\n", DEVNAME(sc), mn, fr, sn); + +done: nvme_dmamem_free(sc, mem); return (rv); @@ -465,36 +492,12 @@ nvme_fill_identify(struct nvme_softc *sc, struct nvme_ccb *ccb, void *slot) { struct nvme_sqe *sqe = slot; struct nvme_dmamem *mem = ccb->ccb_cookie; - struct nvm_identify_controller *identify = NVME_DMA_KVA(mem); - - bus_dmamap_sync(sc->sc_dmat, NVME_DMA_MAP(mem), - 0, sizeof(*identify), BUS_DMASYNC_PREREAD); sqe->opcode = NVM_ADMIN_IDENTIFY; htolem64(&sqe->entry.prp[0], NVME_DMA_DVA(mem)); htolem32(&sqe->cdw10, 1); } -void -nvme_identify_done(struct nvme_softc *sc, struct nvme_ccb *ccb, - struct nvme_cqe *cqe) -{ - struct nvme_dmamem *mem = ccb->ccb_cookie; - struct nvm_identify_controller *identify = NVME_DMA_KVA(mem); - u_int64_t flags = lemtoh16(&cqe->flags); - - bus_dmamap_sync(sc->sc_dmat, NVME_DMA_MAP(mem), - 0, sizeof(*identify), BUS_DMASYNC_POSTREAD); - - printf("%s: dnr %c m %c sqt %x sc %x\n", DEVNAME(sc), - ISSET(flags, NVME_CQE_DNR) ? 'Y' : 'N', - ISSET(flags, NVME_CQE_M) ? 'Y' : 'N', - NVME_CQE_SQT(flags), NVME_CQE_SC(flags)); - - printf("%s: identify %p sn %s mn %s fr %s\n", DEVNAME(sc), mem, - identify->sn, identify->mn, identify->fr); -} - int nvme_ccbs_alloc(struct nvme_softc *sc, u_int nccbs) { diff --git a/sys/dev/ic/nvmereg.h b/sys/dev/ic/nvmereg.h index 951758b342f..97703c972bb 100644 --- a/sys/dev/ic/nvmereg.h +++ b/sys/dev/ic/nvmereg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: nvmereg.h,v 1.3 2014/04/15 10:28:07 dlg Exp $ */ +/* $OpenBSD: nvmereg.h,v 1.4 2014/04/16 00:26:59 dlg Exp $ */ /* * Copyright (c) 2014 David Gwynne <dlg@openbsd.org> @@ -140,8 +140,34 @@ struct nvme_cqe { u_int16_t flags; #define NVME_CQE_DNR (1 << 15) #define NVME_CQE_M (1 << 14) -#define NVME_CQE_SQT(_f) (((_f) >> 8) & 0x7) -#define NVME_CQE_SC(_f) (((_f) >> 1) & 0x7f) +#define NVME_CQE_SCT(_f) ((_f) & (0x07 << 8)) +#define NVME_CQE_SCT_GENERIC (0x00 << 8) +#define NVME_CQE_SCT_COMMAND (0x01 << 8) +#define NVME_CQE_SCT_MEDIAERR (0x02 << 8) +#define NVME_CQE_SCT_VENDOR (0x07 << 8) +#define NVME_CQE_SC(_f) ((_f) & (0x7f << 1)) +#define NVME_CQE_SC_SUCCESS (0x00 << 1) +#define NVME_CQE_SC_INVALID_OPCODE (0x01 << 1) +#define NVME_CQE_SC_INVALID_FIELD (0x02 << 1) +#define NVME_CQE_SC_CID_CONFLICT (0x03 << 1) +#define NVME_CQE_SC_DATA_XFER_ERR (0x04 << 1) +#define NVME_CQE_SC_ABRT_BY_NO_PWR (0x05 << 1) +#define NVME_CQE_SC_INTERNAL_DEV_ERR (0x06 << 1) +#define NVME_CQE_SC_CMD_ABRT_REQD (0x07 << 1) +#define NVME_CQE_SC_CMD_ABDR_SQ_DEL (0x08 << 1) +#define NVME_CQE_SC_CMD_ABDR_FUSE_ERR (0x09 << 1) +#define NVME_CQE_SC_CMD_ABDR_FUSE_MISS (0x0a << 1) +#define NVME_CQE_SC_INVALID_NS (0x0b << 1) +#define NVME_CQE_SC_CMD_SEQ_ERR (0x0c << 1) +#define NVME_CQE_SC_INVALID_LAST_SGL (0x0d << 1) +#define NVME_CQE_SC_INVALID_NUM_SGL (0x0e << 1) +#define NVME_CQE_SC_DATA_SGL_LEN (0x0f << 1) +#define NVME_CQE_SC_MDATA_SGL_LEN (0x10 << 1) +#define NVME_CQE_SC_SGL_TYPE_INVALID (0x11 << 1) +#define NVME_CQE_SC_LBA_RANGE (0x80 << 1) +#define NVME_CQE_SC_CAP_EXCEEDED (0x81 << 1) +#define NVME_CQE_NS_NOT_RDY (0x82 << 1) +#define NVME_CQE_RSV_CONFLICT (0x83 << 1) #define NVME_CQE_PHASE (1 << 0) } __packed __aligned(8); @@ -183,7 +209,7 @@ struct nvm_identify_controller { u_int8_t sn[20]; /* Serial Number */ u_int8_t mn[40]; /* Model Number */ - u_int8_t fr[40]; /* Firmware Revision */ + u_int8_t fr[8]; /* Firmware Revision */ u_int8_t rab; /* Recommended Arbitration Burst */ u_int8_t ieee[3]; /* IEEE OUI Identifier */ |