summaryrefslogtreecommitdiff
path: root/sys/dev/ic
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2016-04-13 12:42:10 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2016-04-13 12:42:10 +0000
commit5635d3ae0b7f0cf9b87ed8313d1526e2835e430b (patch)
tree69920bace30f6ab090a264f82b10d1d2570f65e9 /sys/dev/ic
parent63bb3d1cac6b75460139dcf98031bc133a85eb77 (diff)
implement the guts of the scsi probe and free function
probe issues a namespace identify against the "target". if it works it stashes a copy of the info, otherwise it tells the midlayer to avoid it. free gets rid of the stashed info.
Diffstat (limited to 'sys/dev/ic')
-rw-r--r--sys/dev/ic/nvme.c54
1 files changed, 52 insertions, 2 deletions
diff --git a/sys/dev/ic/nvme.c b/sys/dev/ic/nvme.c
index c95afd8dc79..49af28bff6e 100644
--- a/sys/dev/ic/nvme.c
+++ b/sys/dev/ic/nvme.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nvme.c,v 1.25 2016/04/13 12:28:57 dlg Exp $ */
+/* $OpenBSD: nvme.c,v 1.26 2016/04/13 12:42:09 dlg Exp $ */
/*
* Copyright (c) 2014 David Gwynne <dlg@openbsd.org>
@@ -359,7 +359,51 @@ free_admin_q:
int
nvme_scsi_probe(struct scsi_link *link)
{
- return (ENXIO);
+ struct nvme_softc *sc = link->adapter_softc;
+ struct nvme_sqe sqe;
+ struct nvm_identify_namespace *identify;
+ struct nvme_dmamem *mem;
+ struct nvme_ccb *ccb;
+ int rv;
+
+ ccb = scsi_io_get(&sc->sc_iopool, 0);
+ KASSERT(ccb != NULL);
+
+ mem = nvme_dmamem_alloc(sc, sizeof(*identify));
+ if (mem == NULL)
+ return (ENOMEM);
+
+ memset(&sqe, 0, sizeof(sqe));
+ sqe.opcode = NVM_ADMIN_IDENTIFY;
+ htolem32(&sqe.nsid, link->target + 1);
+ htolem64(&sqe.entry.prp[0], NVME_DMA_DVA(mem));
+ htolem32(&sqe.cdw10, 0);
+
+ ccb->ccb_done = nvme_empty_done;
+ ccb->ccb_cookie = &sqe;
+
+ nvme_dmamem_sync(sc, mem, BUS_DMASYNC_PREREAD);
+ rv = nvme_poll(sc, sc->sc_admin_q, ccb, nvme_sqe_fill);
+ nvme_dmamem_sync(sc, mem, BUS_DMASYNC_POSTREAD);
+
+ scsi_io_put(&sc->sc_iopool, ccb);
+
+ if (rv != 0) {
+ rv = EIO;
+ goto done;
+ }
+
+ /* commit */
+
+ identify = malloc(sizeof(*identify), M_DEVBUF, M_WAITOK|M_ZERO);
+ memcpy(identify, NVME_DMA_KVA(mem), sizeof(*identify));
+
+ sc->sc_namespaces[link->target].ident = identify;
+
+done:
+ nvme_dmamem_free(sc, mem);
+
+ return (rv);
}
void
@@ -372,7 +416,13 @@ nvme_scsi_cmd(struct scsi_xfer *xs)
void
nvme_scsi_free(struct scsi_link *link)
{
+ struct nvme_softc *sc = link->adapter_softc;
+ struct nvm_identify_namespace *identify;
+
+ identify = sc->sc_namespaces[link->target].ident;
+ sc->sc_namespaces[link->target].ident = NULL;
+ free(identify, M_DEVBUF, sizeof(*identify));
}
void