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 @@ -60,11 +60,6 @@ static void nvd_done(void *arg, const struct nvme_completion *cpl); static void nvd_gone(struct nvd_disk *ndisk); -static void *nvd_new_disk(struct nvme_namespace *ns, void *ctrlr); - -static void *nvd_new_controller(struct nvme_controller *ctrlr); -static void nvd_controller_fail(void *ctrlr); - static int nvd_load(void); static void nvd_unload(void); @@ -148,16 +143,12 @@ nvd_load(void) { if (!nvme_use_nvd) - return 0; + return (0); mtx_init(&nvd_lock, "nvd_lock", NULL, MTX_DEF); TAILQ_INIT(&ctrlr_head); TAILQ_INIT(&disk_head); - - consumer_handle = nvme_register_consumer(nvd_new_disk, - nvd_new_controller, NULL, nvd_controller_fail); - - return (consumer_handle != NULL ? 0 : -1); + return (0); } static void @@ -394,30 +385,12 @@ } } -static void * -nvd_new_controller(struct nvme_controller *ctrlr) -{ - struct nvd_controller *nvd_ctrlr; - - nvd_ctrlr = malloc(sizeof(struct nvd_controller), M_NVD, - M_ZERO | M_WAITOK); - - 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 (nvd_ctrlr); -} - -static void * -nvd_new_disk(struct nvme_namespace *ns, void *ctrlr_arg) +static void +nvd_new_disk(struct nvme_namespace *ns, struct nvd_controller *ctrlr) { uint8_t descr[NVME_MODEL_NUMBER_LENGTH+1]; struct nvd_disk *ndisk, *tnd; struct disk *disk; - struct nvd_controller *ctrlr = ctrlr_arg; device_t dev = ctrlr->ctrlr->dev; int unit; @@ -508,14 +481,12 @@ (uintmax_t)disk->d_mediasize / (1024*1024), (uintmax_t)disk->d_mediasize / disk->d_sectorsize, disk->d_sectorsize); - - return (ndisk); } -static void -nvd_controller_fail(void *ctrlr_arg) +static int +nvdc_fail(device_t dev) { - struct nvd_controller *ctrlr = ctrlr_arg; + struct nvd_controller *ctrlr = device_get_softc(dev); struct nvd_disk *ndisk; mtx_lock(&nvd_lock); @@ -525,5 +496,60 @@ while (!TAILQ_EMPTY(&ctrlr->disk_head)) msleep(&ctrlr->disk_head, &nvd_lock, 0, "nvd_fail", 0); mtx_unlock(&nvd_lock); - free(ctrlr, M_NVD); + return (0); +} + +static int +nvdc_probe(device_t dev) +{ + if (!nvme_use_nvd) + return (ENXIO); + + device_set_desc(dev, "NVME CAM bus"); + 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) +{ + return (nvdc_fail(dev)); } + +static device_method_t nvdc_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, nvdc_probe), + DEVMETHOD(device_attach, nvdc_attach), + DEVMETHOD(device_detach, nvdc_detach), + { 0, 0 } +}; + +static driver_t nvdc_driver = { + "nvdc", + nvdc_methods, + sizeof(struct nvd_controller), +}; + +DRIVER_MODULE(nvdc, nvme, nvdc_driver, NULL, NULL);