summaryrefslogtreecommitdiff
path: root/sys/dev/ic
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2016-04-13 12:59:29 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2016-04-13 12:59:29 +0000
commit01d0916d48a3b61330263c0d1ff55bfb7ebbebbb (patch)
treec021a88f2ace5a85949ea215a299cc3df71a6d77 /sys/dev/ic
parentf2cb276f5d48fe6ecc5266293e99ca566550eba6 (diff)
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.
Diffstat (limited to 'sys/dev/ic')
-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;