Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F161357346
D51387.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D51387.id.diff
View Options
diff --git a/sys/dev/nvme/nvme_sim.c b/sys/dev/nvme/nvme_sim.c
--- a/sys/dev/nvme/nvme_sim.c
+++ b/sys/dev/nvme/nvme_sim.c
@@ -44,10 +44,15 @@
#include "nvme_private.h"
+#include "nvme_if.h"
+
#define ccb_accb_ptr spriv_ptr0
#define ccb_ctrlr_ptr spriv_ptr1
static void nvme_sim_action(struct cam_sim *sim, union ccb *ccb);
static void nvme_sim_poll(struct cam_sim *sim);
+static int nvme_sim_ns_added(device_t dev, struct nvme_namespace *ns);
+static int nvme_sim_ns_changed(device_t dev, uint32_t nsid);
+static int nvme_sim_ns_removed(device_t dev, struct nvme_namespace *ns);
#define sim2softc(sim) ((struct nvme_sim_softc *)cam_sim_softc(sim))
#define sim2ctrlr(sim) (sim2softc(sim)->s_ctrlr)
@@ -304,26 +309,6 @@
nvme_ctrlr_poll(sim2ctrlr(sim));
}
-static void
-nvme_sim_ns_change(struct nvme_namespace *ns, struct nvme_sim_softc *sc)
-{
- union ccb *ccb;
-
- /*
- * We map the NVMe namespace idea onto the CAM unit LUN. For each new
- * namespace, we create a new CAM path for it. We then rescan the path
- * to get it to enumerate.
- */
- ccb = xpt_alloc_ccb();
- if (xpt_create_path(&ccb->ccb_h.path, /*periph*/NULL,
- cam_sim_path(sc->s_sim), 0, ns->id) != CAM_REQ_CMP) {
- printf("unable to create path for rescan\n");
- xpt_free_ccb(ccb);
- return;
- }
- xpt_rescan(ccb);
-}
-
static int
nvme_sim_probe(device_t dev)
{
@@ -339,7 +324,7 @@
{
struct cam_devq *devq;
int max_trans;
- int err = ENOMEM;
+ int err = ENXIO;
struct nvme_sim_softc *sc = device_get_softc(dev);
struct nvme_controller *ctrlr = device_get_ivars(dev);
@@ -356,16 +341,14 @@
if (sc->s_sim == NULL) {
device_printf(dev, "Failed to allocate a sim\n");
cam_simq_free(devq);
- goto err1;
+ return (ENOMEM);
}
if (xpt_bus_register(sc->s_sim, dev, 0) != CAM_SUCCESS) {
- err = ENXIO;
device_printf(dev, "Failed to create a bus\n");
goto err2;
}
if (xpt_create_path(&sc->s_path, /*periph*/NULL, cam_sim_path(sc->s_sim),
CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
- err = ENXIO;
device_printf(dev, "Failed to create a path\n");
goto err3;
}
@@ -375,7 +358,7 @@
if (ns->data.nsze == 0)
continue;
- nvme_sim_ns_change(ns, sc);
+ nvme_sim_ns_added(dev, ns);
}
return (0);
@@ -383,69 +366,109 @@
xpt_bus_deregister(cam_sim_path(sc->s_sim));
err2:
cam_sim_free(sc->s_sim, /*free_devq*/TRUE);
-err1:
- free(sc, M_NVME);
return (err);
}
+
static int
-nvme_sim_fail(device_t dev, struct nvme_namespace *ns)
+nvme_sim_fail_all_ns(device_t dev)
{
struct nvme_sim_softc *sc = device_get_softc(dev);
- struct cam_path *tmppath;
- union ccb *ccb;
+ struct nvme_controller *ctrlr = sc->s_ctrlr;
- if (xpt_create_path(&tmppath, /*periph*/NULL,
- cam_sim_path(sc->s_sim), 0, ns->id) != CAM_REQ_CMP) {
- device_printf(dev, "unable to create path for rescan\n");
- return (ENOMEM);
- }
- /*
- * If it's gone, then signal that and leave.
- */
- if (ns->flags & NVME_NS_GONE) {
- xpt_async(AC_LOST_DEVICE, tmppath, NULL);
- xpt_free_path(tmppath);
- return (0);
- }
+ for (int i = 0; i < min(ctrlr->cdata.nn, NVME_MAX_NAMESPACES); i++) {
+ struct nvme_namespace *ns = &ctrlr->ns[i];
- ccb = xpt_alloc_ccb_nowait();
- if (ccb == NULL) {
- device_printf(dev, "unable to alloc CCB for rescan\n");
- return (ENOMEM);
+ if (ns->data.nsze == 0)
+ continue;
+ nvme_sim_ns_removed(dev, ns);
}
- ccb->ccb_h.path = tmppath;
+ return (0);
+}
+
+static int
+nvme_sim_detach(device_t dev)
+{
+ return (nvme_sim_fail_all_ns(dev));
+}
+
+static int
+nvme_sim_ns_added(device_t dev, struct nvme_namespace *ns)
+{
+ struct nvme_sim_softc *sc = device_get_softc(dev);
+ union ccb *ccb;
/*
* We map the NVMe namespace idea onto the CAM unit LUN. For each new
- * namespace, scan or rescan the path to enumerate it. tmppath freed at
- * end of scan.
+ * namespace, scan or rescan the path to enumerate it.
*/
+ ccb = xpt_alloc_ccb();
+ if (xpt_create_path(&ccb->ccb_h.path, /*periph*/NULL,
+ cam_sim_path(sc->s_sim), 0, ns->id) != CAM_REQ_CMP) {
+ printf("unable to create path for rescan\n");
+ return (ENOMEM);
+ }
xpt_rescan(ccb);
return (0);
}
static int
-nvme_sim_detach(device_t dev)
+nvme_sim_ns_removed(device_t dev, struct nvme_namespace *ns)
{
- struct nvme_controller *ctrlr = device_get_ivars(dev);
-
- for (int i = 0; i < min(ctrlr->cdata.nn, NVME_MAX_NAMESPACES); i++) {
- struct nvme_namespace *ns = &ctrlr->ns[i];
+ struct nvme_sim_softc *sc = device_get_softc(dev);
+ struct cam_path *tmppath;
- if (ns->data.nsze == 0)
- continue;
- nvme_sim_fail(dev, ns);
+ if (xpt_create_path(&tmppath, /*periph*/NULL,
+ cam_sim_path(sc->s_sim), 0, ns->id) != CAM_REQ_CMP) {
+ printf("unable to create path for rescan\n");
+ return (ENOMEM);
}
+ xpt_async(AC_LOST_DEVICE, tmppath, NULL);
+ xpt_free_path(tmppath);
+
+ return (0);
+}
+
+static int
+nvme_sim_ns_changed(device_t dev, uint32_t nsid)
+{
+ struct nvme_sim_softc *sc = device_get_softc(dev);
+ struct nvme_namespace *ns = &sc->s_ctrlr->ns[nsid - 1];
+
+ /*
+ * These wind up being the same. For a configured cam_ed, we generate
+ * AC_GETDEV_CHANGED, but for new one we do AC_FOUND_DEVICE, but the
+ * scan is the same.
+ */
+ return (nvme_sim_ns_added(dev, ns));
+}
+
+static int
+nvme_sim_controller_failed(device_t dev)
+{
+ return (nvme_sim_fail_all_ns(dev));
+}
+
+static int
+nvme_sim_handle_aen(device_t dev, const struct nvme_completion *cpl,
+ uint32_t pg_nr, void *page, uint32_t page_len)
+{
+ /* Do nothing */
return (0);
}
static device_method_t nvme_sim_methods[] = {
/* Device interface */
- DEVMETHOD(device_probe, nvme_sim_probe),
- DEVMETHOD(device_attach, nvme_sim_attach),
- DEVMETHOD(device_detach, nvme_sim_detach),
+ DEVMETHOD(device_probe, nvme_sim_probe),
+ DEVMETHOD(device_attach, nvme_sim_attach),
+ DEVMETHOD(device_detach, nvme_sim_detach),
+ /* Nvme controller messages */
+ DEVMETHOD(nvme_ns_added, nvme_sim_ns_added),
+ DEVMETHOD(nvme_ns_removed, nvme_sim_ns_removed),
+ DEVMETHOD(nvme_ns_changed, nvme_sim_ns_changed),
+ DEVMETHOD(nvme_controller_failed, nvme_sim_controller_failed),
+ DEVMETHOD(nvme_handle_aen, nvme_sim_handle_aen),
{ 0, 0 }
};
diff --git a/sys/modules/nvme/Makefile b/sys/modules/nvme/Makefile
--- a/sys/modules/nvme/Makefile
+++ b/sys/modules/nvme/Makefile
@@ -16,6 +16,7 @@
\
bus_if.h \
device_if.h \
+ nvme_if.h \
opt_cam.h \
opt_nvme.h \
pci_if.h
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Jul 4, 3:18 AM (11 h, 45 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34628193
Default Alt Text
D51387.id.diff (6 KB)
Attached To
Mode
D51387: nvme_sim: Connect to events broadcast with nvme_if
Attached
Detach File
Event Timeline
Log In to Comment