diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2016-04-13 12:59:29 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2016-04-13 12:59:29 +0000 |
commit | 01d0916d48a3b61330263c0d1ff55bfb7ebbebbb (patch) | |
tree | c021a88f2ace5a85949ea215a299cc3df71a6d77 /sys/dev/ic | |
parent | f2cb276f5d48fe6ecc5266293e99ca566550eba6 (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.c | 60 |
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; |