summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordlg <dlg@openbsd.org>2016-04-13 12:59:28 +0000
committerdlg <dlg@openbsd.org>2016-04-13 12:59:28 +0000
commit9856392ea9ca695a29db00ba75b84032ce07d6ba (patch)
tree198a915d3982f2302ce70533b42f3a5693561774
parentGive manuals in purely numerical sections priority over manuals of (diff)
downloadwireguard-openbsd-9856392ea9ca695a29db00ba75b84032ce07d6ba.tar.xz
wireguard-openbsd-9856392ea9ca695a29db00ba75b84032ce07d6ba.zip
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.
-rw-r--r--sys/dev/ic/nvme.c60
1 files changed, 59 insertions, 1 deletions
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 <dlg@openbsd.org>
@@ -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,11 +412,66 @@ 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)
{
struct nvme_softc *sc = link->adapter_softc;