From 01d0916d48a3b61330263c0d1ff55bfb7ebbebbb Mon Sep 17 00:00:00 2001 From: David Gwynne Date: Wed, 13 Apr 2016 12:59:29 +0000 Subject: implement basic scsi inquiry handling most values are as per the nvm to scsi mapping guide. this doesnt do vpd at all, so no devids or serial numbers just yet. --- sys/dev/ic/nvme.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) (limited to 'sys/dev/ic') diff --git a/sys/dev/ic/nvme.c b/sys/dev/ic/nvme.c index 49af28bff6e..4f5d7907e55 100644 --- a/sys/dev/ic/nvme.c +++ b/sys/dev/ic/nvme.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nvme.c,v 1.26 2016/04/13 12:42:09 dlg Exp $ */ +/* $OpenBSD: nvme.c,v 1.27 2016/04/13 12:59:28 dlg Exp $ */ /* * Copyright (c) 2014 David Gwynne @@ -90,6 +90,9 @@ struct scsi_adapter nvme_switch = { NULL, /* ioctl */ }; +void nvme_scsi_inq(struct scsi_xfer *); +void nvme_scsi_inquiry(struct scsi_xfer *); + #define nvme_read4(_s, _r) \ bus_space_read_4((_s)->sc_iot, (_s)->sc_ioh, (_r)) #define nvme_write4(_s, _r, _v) \ @@ -409,10 +412,65 @@ done: void nvme_scsi_cmd(struct scsi_xfer *xs) { + switch (xs->cmd->opcode) { + case INQUIRY: + nvme_scsi_inq(xs); + return; + default: + break; + } + xs->error = XS_DRIVER_STUFFUP; scsi_done(xs); } +void +nvme_scsi_inq(struct scsi_xfer *xs) +{ + struct scsi_inquiry *inq = (struct scsi_inquiry *)xs->cmd; + + if (!ISSET(inq->flags, SI_EVPD)) { + nvme_scsi_inquiry(xs); + return; + } + + switch (inq->pagecode) { + default: + /* printf("%s: %d\n", __func__, inq->pagecode); */ + break; + } + + xs->error = XS_DRIVER_STUFFUP; + scsi_done(xs); +} + +void +nvme_scsi_inquiry(struct scsi_xfer *xs) +{ + struct scsi_inquiry_data inq; + struct scsi_link *link = xs->sc_link; + struct nvme_softc *sc = link->adapter_softc; + struct nvm_identify_namespace *ns; + + ns = sc->sc_namespaces[link->target].ident; + + memset(&inq, 0, sizeof(inq)); + + inq.device = T_DIRECT; + inq.version = 0x06; /* SPC-4 */ + inq.response_format = 2; + inq.additional_length = 32; + inq.flags |= SID_CmdQue; + memcpy(inq.vendor, "NVMe ", sizeof(inq.vendor)); + memcpy(inq.product, sc->sc_identify.mn, sizeof(inq.product)); + memcpy(inq.revision, sc->sc_identify.fr, sizeof(inq.revision)); + + memcpy(xs->data, &inq, MIN(sizeof(inq), xs->datalen)); + + xs->error = XS_NOERROR; + scsi_done(xs); +} + void nvme_scsi_free(struct scsi_link *link) { -- cgit v1.2.3