Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F143875752
D51388.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
12 KB
Referenced Files
None
Subscribers
None
D51388.id.diff
View Options
diff --git a/sys/dev/nvd/nvd.c b/sys/dev/nvd/nvd.c
--- a/sys/dev/nvd/nvd.c
+++ b/sys/dev/nvd/nvd.c
@@ -29,6 +29,7 @@
#include <sys/param.h>
#include <sys/bio.h>
+#include <sys/bus.h>
#include <sys/devicestat.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
@@ -47,6 +48,8 @@
#include <dev/pci/pcivar.h>
+#include "nvme_if.h"
+
#define NVD_STR "nvd"
struct nvd_disk;
@@ -385,17 +388,96 @@
}
}
-static void
-nvd_new_disk(struct nvme_namespace *ns, struct nvd_controller *ctrlr)
+static int
+nvdc_controller_failed(device_t dev)
+{
+ struct nvd_controller *nvd_ctrlr = device_get_softc(dev);
+ struct nvd_disk *ndisk;
+
+ mtx_lock(&nvd_lock);
+ TAILQ_REMOVE(&ctrlr_head, nvd_ctrlr, tailq);
+ TAILQ_FOREACH(ndisk, &nvd_ctrlr->disk_head, ctrlr_tailq)
+ nvd_gone(ndisk);
+ while (!TAILQ_EMPTY(&nvd_ctrlr->disk_head))
+ msleep(&nvd_ctrlr->disk_head, &nvd_lock, 0, "nvd_fail", 0);
+ mtx_unlock(&nvd_lock);
+ return (0);
+}
+
+static int
+nvdc_probe(device_t dev)
+{
+ if (!nvme_use_nvd)
+ return (ENXIO);
+
+ device_set_desc(dev, "nvme storage namespace");
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+nvdc_attach(device_t dev)
+{
+ struct nvd_controller *nvd_ctrlr = device_get_softc(dev);
+ struct nvme_controller *ctrlr = device_get_ivars(dev);
+
+ nvd_ctrlr->ctrlr = ctrlr;
+ TAILQ_INIT(&nvd_ctrlr->disk_head);
+ mtx_lock(&nvd_lock);
+ TAILQ_INSERT_TAIL(&ctrlr_head, nvd_ctrlr, tailq);
+ mtx_unlock(&nvd_lock);
+
+ return (0);
+}
+
+static int
+nvdc_detach(device_t dev)
+{
+ return (nvdc_controller_failed(dev));
+}
+
+static struct nvd_disk *
+nvd_nsid_to_disk(struct nvd_controller *nvd_ctrlr, uint32_t nsid)
+{
+ struct nvd_disk *ndisk;
+
+ mtx_lock(&nvd_lock);
+ TAILQ_FOREACH(ndisk, &nvd_ctrlr->disk_head, ctrlr_tailq) {
+ if (ndisk->ns->id != nsid)
+ continue;
+ break;
+ }
+ mtx_unlock(&nvd_lock);
+ return ndisk;
+}
+
+static struct nvd_disk *
+nvd_ns_to_disk(struct nvd_controller *nvd_ctrlr, struct nvme_namespace *ns)
{
+ struct nvd_disk *ndisk;
+
+ mtx_lock(&nvd_lock);
+ TAILQ_FOREACH(ndisk, &nvd_ctrlr->disk_head, ctrlr_tailq) {
+ if (ndisk->ns != ns)
+ continue;
+ break;
+ }
+ mtx_unlock(&nvd_lock);
+ return ndisk;
+}
+
+static int
+nvdc_ns_added(device_t dev, struct nvme_namespace *ns)
+{
+ struct nvd_controller *nvd_ctrlr = device_get_softc(dev);
+ struct nvd_disk *ndisk;
uint8_t descr[NVME_MODEL_NUMBER_LENGTH+1];
- struct nvd_disk *ndisk, *tnd;
+ struct nvd_disk *tnd;
struct disk *disk;
- device_t dev = ctrlr->ctrlr->dev;
- int unit;
+ device_t pdev = nvd_ctrlr->ctrlr->dev;
+ int unit;
ndisk = malloc(sizeof(struct nvd_disk), M_NVD, M_ZERO | M_WAITOK);
- ndisk->ctrlr = ctrlr;
+ ndisk->ctrlr = nvd_ctrlr;
ndisk->ns = ns;
ndisk->cur_depth = 0;
ndisk->ordered_in_flight = 0;
@@ -415,7 +497,7 @@
TAILQ_INSERT_BEFORE(tnd, ndisk, global_tailq);
else
TAILQ_INSERT_TAIL(&disk_head, ndisk, global_tailq);
- TAILQ_INSERT_TAIL(&ctrlr->disk_head, ndisk, ctrlr_tailq);
+ TAILQ_INSERT_TAIL(&nvd_ctrlr->disk_head, ndisk, ctrlr_tailq);
mtx_unlock(&nvd_lock);
ndisk->tq = taskqueue_create("nvd_taskq", M_WAITOK,
@@ -464,14 +546,14 @@
* which has no access to the config space for this controller, report
* the AHCI controller's data.
*/
- if (ctrlr->ctrlr->quirks & QUIRK_AHCI)
- dev = device_get_parent(dev);
- disk->d_hba_vendor = pci_get_vendor(dev);
- disk->d_hba_device = pci_get_device(dev);
- disk->d_hba_subvendor = pci_get_subvendor(dev);
- disk->d_hba_subdevice = pci_get_subdevice(dev);
+ if (nvd_ctrlr->ctrlr->quirks & QUIRK_AHCI)
+ pdev = device_get_parent(pdev);
+ disk->d_hba_vendor = pci_get_vendor(pdev);
+ disk->d_hba_device = pci_get_device(pdev);
+ disk->d_hba_subvendor = pci_get_subvendor(pdev);
+ disk->d_hba_subdevice = pci_get_subdevice(pdev);
disk->d_rotation_rate = DISK_RR_NON_ROTATING;
- strlcpy(disk->d_attachment, device_get_nameunit(dev),
+ strlcpy(disk->d_attachment, device_get_nameunit(pdev),
sizeof(disk->d_attachment));
disk_create(disk, DISK_VERSION);
@@ -481,14 +563,35 @@
(uintmax_t)disk->d_mediasize / (1024*1024),
(uintmax_t)disk->d_mediasize / disk->d_sectorsize,
disk->d_sectorsize);
+
+ return (0);
}
-#if 0
-static void
-nvd_resize(struct nvd_disk *ndisk)
+static int
+nvdc_ns_removed(device_t dev, struct nvme_namespace *ns)
{
- struct disk *disk = ndisk->disk;
- struct nvme_namespace *ns = ndisk->ns;
+ struct nvd_controller *nvd_ctrlr = device_get_softc(dev);
+ struct nvd_disk *ndisk = nvd_ns_to_disk(nvd_ctrlr, ns);
+
+ if (ndisk == NULL)
+ panic("nvdc: no namespace found for ns %p", ns);
+ nvd_gone(ndisk);
+ /* gonecb removes it from the list -- no need to wait */
+ return (0);
+}
+
+static int
+nvdc_ns_changed(device_t dev, uint32_t nsid)
+{
+ struct nvd_controller *nvd_ctrlr = device_get_softc(dev);
+ struct nvd_disk *ndisk = nvd_nsid_to_disk(nvd_ctrlr, nsid);
+ struct disk *disk;
+ struct nvme_namespace *ns;
+
+ if (ndisk == NULL)
+ panic("nvdc: no namespace found for %d", nsid);
+ disk = ndisk->disk;
+ ns = ndisk->ns;
disk->d_sectorsize = nvme_ns_get_sector_size(ns);
disk->d_mediasize = (off_t)nvme_ns_get_size(ns);
@@ -504,98 +607,28 @@
(uintmax_t)disk->d_mediasize / (1024*1024),
(uintmax_t)disk->d_mediasize / disk->d_sectorsize,
disk->d_sectorsize);
-}
-#endif
-
-static int
-nvdc_fail(device_t dev)
-{
- return ENXIO;
-}
-
-#if 0
-static void *
-nvd_ns_changed(struct nvme_namespace *ns, void *ctrlr_arg)
-{
- struct nvd_disk *ndisk;
- struct nvd_controller *ctrlr = ctrlr_arg;
-
- if ((ns->flags & NVME_NS_DELTA) == 0) {
- nvd_new_disk(ns, ctrlr_arg);
- return (ctrlr_arg);
- }
-
- mtx_lock(&nvd_lock);
- TAILQ_FOREACH(ndisk, &ctrlr->disk_head, ctrlr_tailq) {
- if (ndisk->ns->id != ns->id)
- continue;
- nvd_resize(ndisk);
- break;
- }
- mtx_unlock(&nvd_lock);
- return (ctrlr_arg);
-}
-
-static void
-nvd_controller_fail(void *ctrlr_arg)
-{
- struct nvd_controller *ctrlr = ctrlr_arg;
- struct nvd_disk *ndisk;
-
- mtx_lock(&nvd_lock);
- TAILQ_REMOVE(&ctrlr_head, ctrlr, tailq);
- TAILQ_FOREACH(ndisk, &ctrlr->disk_head, ctrlr_tailq)
- nvd_gone(ndisk);
- while (!TAILQ_EMPTY(&ctrlr->disk_head))
- msleep(&ctrlr->disk_head, &nvd_lock, 0, "nvd_fail", 0);
- mtx_unlock(&nvd_lock);
-}
-#endif
-
-static int
-nvdc_probe(device_t dev)
-{
- if (!nvme_use_nvd)
- return (ENXIO);
-
- device_set_desc(dev, "nvme storage namespace");
- return (BUS_PROBE_DEFAULT);
-}
-
-static int
-nvdc_attach(device_t dev)
-{
- struct nvd_controller *nvd_ctrlr = device_get_softc(dev);
- struct nvme_controller *ctrlr = device_get_ivars(dev);
-
- nvd_ctrlr->ctrlr = ctrlr;
- TAILQ_INIT(&nvd_ctrlr->disk_head);
- mtx_lock(&nvd_lock);
- TAILQ_INSERT_TAIL(&ctrlr_head, nvd_ctrlr, tailq);
- mtx_unlock(&nvd_lock);
-
- for (int i = 0; i < min(ctrlr->cdata.nn, NVME_MAX_NAMESPACES); i++) {
- struct nvme_namespace *ns = &ctrlr->ns[i];
-
- if (ns->data.nsze == 0)
- continue;
- nvd_new_disk(ns, nvd_ctrlr);
- }
-
return (0);
}
static int
-nvdc_detach(device_t dev)
+nvdc_handle_aen(device_t dev, const struct nvme_completion *cpl,
+ uint32_t pg_nr, void *page, uint32_t page_len)
{
- return (nvdc_fail(dev));
+ /* Do nothing */
+ return (0);
}
static device_method_t nvdc_methods[] = {
/* Device interface */
- DEVMETHOD(device_probe, nvdc_probe),
- DEVMETHOD(device_attach, nvdc_attach),
- DEVMETHOD(device_detach, nvdc_detach),
+ DEVMETHOD(device_probe, nvdc_probe),
+ DEVMETHOD(device_attach, nvdc_attach),
+ DEVMETHOD(device_detach, nvdc_detach),
+ /* Nvme controller messages */
+ DEVMETHOD(nvme_ns_added, nvdc_ns_added),
+ DEVMETHOD(nvme_ns_removed, nvdc_ns_removed),
+ DEVMETHOD(nvme_ns_changed, nvdc_ns_changed),
+ DEVMETHOD(nvme_controller_failed, nvdc_controller_failed),
+ DEVMETHOD(nvme_handle_aen, nvdc_handle_aen),
{ 0, 0 }
};
diff --git a/sys/dev/nvme/nvme.c b/sys/dev/nvme/nvme.c
--- a/sys/dev/nvme/nvme.c
+++ b/sys/dev/nvme/nvme.c
@@ -170,18 +170,6 @@
}
}
-void
-nvme_notify_new_controller(struct nvme_controller *ctrlr)
-{
- int i;
-
- for (i = 0; i < NVME_MAX_CONSUMERS; i++) {
- if (nvme_consumer[i].id != INVALID_CONSUMER_ID) {
- nvme_notify(&nvme_consumer[i], ctrlr);
- }
- }
-}
-
static void
nvme_notify_new_consumer(struct nvme_consumer *cons)
{
@@ -247,30 +235,6 @@
}
}
-void
-nvme_notify_ns(struct nvme_controller *ctrlr, int nsid)
-{
- struct nvme_consumer *cons;
- struct nvme_namespace *ns;
- void *ctrlr_cookie;
- uint32_t i;
-
- KASSERT(nsid <= NVME_MAX_NAMESPACES,
- ("%s: Namespace notification to nsid %d exceeds range\n",
- device_get_nameunit(ctrlr->dev), nsid));
-
- if (!ctrlr->is_initialized)
- return;
-
- ns = &ctrlr->ns[nsid - 1];
- for (i = 0; i < NVME_MAX_CONSUMERS; i++) {
- cons = &nvme_consumer[i];
- if (cons->id != INVALID_CONSUMER_ID && cons->ns_fn != NULL &&
- (ctrlr_cookie = ctrlr->cons_cookie[i]) != NULL)
- ns->cons_cookie[i] = (*cons->ns_fn)(ns, ctrlr_cookie);
- }
-}
-
struct nvme_consumer *
nvme_register_consumer(nvme_cons_ns_fn_t ns_fn, nvme_cons_ctrlr_fn_t ctrlr_fn,
nvme_cons_async_fn_t async_fn,
diff --git a/sys/dev/nvme/nvme_ctrlr.c b/sys/dev/nvme/nvme_ctrlr.c
--- a/sys/dev/nvme/nvme_ctrlr.c
+++ b/sys/dev/nvme/nvme_ctrlr.c
@@ -48,6 +48,8 @@
#include "nvme_private.h"
#include "nvme_linux.h"
+#include "nvme_if.h"
+
#define B4_CHK_RDY_DELAY_MS 2300 /* work around controller bug */
static void nvme_ctrlr_construct_and_submit_aer(struct nvme_controller *ctrlr,
@@ -1082,10 +1084,20 @@
device_t child;
ctrlr->is_initialized = true;
- nvme_notify_new_controller(ctrlr);
child = device_add_child(ctrlr->dev, NULL, DEVICE_UNIT_ANY);
device_set_ivars(child, ctrlr);
bus_attach_children(ctrlr->dev);
+
+ /*
+ * Now notify the child of all the known namepsaces
+ */
+ for (int i = 0; i < min(ctrlr->cdata.nn, NVME_MAX_NAMESPACES); i++) {
+ struct nvme_namespace *ns = &ctrlr->ns[i];
+
+ if (ns->data.nsze == 0)
+ continue;
+ NVME_NS_ADDED(child, ns);
+ }
}
TSEXIT();
}
@@ -1223,23 +1235,26 @@
nvme_ctrlr_cmd_set_async_event_config(aer->ctrlr,
aer->ctrlr->async_event_config, NULL, NULL);
} else if (aer->log_page_id == NVME_LOG_CHANGED_NAMESPACE) {
- struct nvme_ns_list *nsl =
- (struct nvme_ns_list *)aer->log_page_buffer;
- struct nvme_controller *ctrlr = aer->ctrlr;
+ device_t *children;
+ int n_children;
+ struct nvme_ns_list *nsl;
+ if (device_get_children(aer->ctrlr->dev, &children, &n_children) != 0) {
+ children = NULL;
+ n_children = 0;
+ }
+ nsl = (struct nvme_ns_list *)aer->log_page_buffer;
for (int i = 0; i < nitems(nsl->ns) && nsl->ns[i] != 0; i++) {
- struct nvme_namespace *ns;
- uint32_t id = nsl->ns[i];
-
- if (nsl->ns[i] > NVME_MAX_NAMESPACES)
- break;
-
- ns = &ctrlr->ns[id - 1];
- ns->flags |= NVME_NS_DELTA;
- nvme_ns_construct(ns, id, ctrlr);
- nvme_notify_ns(ctrlr, id);
- ns->flags &= ~NVME_NS_DELTA;
+ /*
+ * I think we need to query the name space here and see
+ * if it went away, arrived, or changed in size and call
+ * the nuanced routine (after constructing or before
+ * destructing the namespace). XXX needs more work XXX.
+ */
+ for (int j = 0; j < n_children; j++)
+ NVME_NS_CHANGED(children[j], nsl->ns[i]);
}
+ free(children, M_TEMP);
}
/*
diff --git a/sys/dev/nvme/nvme_if.m b/sys/dev/nvme/nvme_if.m
--- a/sys/dev/nvme/nvme_if.m
+++ b/sys/dev/nvme/nvme_if.m
@@ -33,7 +33,7 @@
#
METHOD int ns_changed {
device_t dev; /* nvme device */
- struct nvme_namespace *ns; /* information about the namespace */
+ uint32_t nsid; /* nsid that just changed */
};
#
diff --git a/sys/dev/nvme/nvme_private.h b/sys/dev/nvme/nvme_private.h
--- a/sys/dev/nvme/nvme_private.h
+++ b/sys/dev/nvme/nvme_private.h
@@ -561,8 +561,6 @@
uint32_t log_page_id, void *log_page_buffer,
uint32_t log_page_size);
void nvme_notify_fail_consumers(struct nvme_controller *ctrlr);
-void nvme_notify_new_controller(struct nvme_controller *ctrlr);
-void nvme_notify_ns(struct nvme_controller *ctrlr, int nsid);
void nvme_ctrlr_shared_handler(void *arg);
void nvme_ctrlr_poll(struct nvme_controller *ctrlr);
diff --git a/sys/modules/nvd/Makefile b/sys/modules/nvd/Makefile
--- a/sys/modules/nvd/Makefile
+++ b/sys/modules/nvd/Makefile
@@ -1,6 +1,6 @@
.PATH: ${SRCTOP}/sys/dev/nvd
KMOD= nvd
-SRCS= nvd.c opt_geom.h device_if.h bus_if.h pci_if.h
+SRCS= nvd.c opt_geom.h device_if.h bus_if.h nvme_if.h pci_if.h
.include <bsd.kmod.mk>
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Feb 2, 9:18 AM (3 h, 31 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28411709
Default Alt Text
D51388.id.diff (12 KB)
Attached To
Mode
D51388: nvd: Connect nvme_if methods
Attached
Detach File
Event Timeline
Log In to Comment