From 56765aa39fd9b27e603655e5d156bece9d9e9f35 Mon Sep 17 00:00:00 2001 From: Cunyin Chang Date: Tue, 15 Nov 2016 09:53:14 +0800 Subject: [PATCH] env_dpdk: Add spdk_pci_device_[attach|detach] These functions will attach or detach from a PCI device. Attaching typically means mapping the BAR. Change-Id: Iaaf59010b8a0366d32ec80bb90c1c277ada7cfe7 Signed-off-by: Cunyin Chang --- include/spdk/env.h | 4 +++ lib/env_dpdk/pci.c | 64 +++++++++++++++++++++++++++++++++++++++----- lib/nvme/nvme_pcie.c | 1 + 3 files changed, 62 insertions(+), 7 deletions(-) diff --git a/include/spdk/env.h b/include/spdk/env.h index f25afc7c6b..d30e4529c2 100644 --- a/include/spdk/env.h +++ b/include/spdk/env.h @@ -212,6 +212,10 @@ struct spdk_pci_id spdk_pci_device_get_id(struct spdk_pci_device *dev); int spdk_pci_device_get_serial_number(struct spdk_pci_device *dev, char *sn, size_t len); int spdk_pci_device_claim(const struct spdk_pci_addr *pci_addr); +void spdk_pci_device_detach(struct spdk_pci_device *device); +int spdk_pci_device_attach(enum spdk_pci_device_type type, + spdk_pci_enum_cb enum_cb, + void *enum_ctx, struct spdk_pci_addr *pci_addres); int spdk_pci_device_cfg_read8(struct spdk_pci_device *dev, uint8_t *value, uint32_t offset); int spdk_pci_device_cfg_write8(struct spdk_pci_device *dev, uint8_t value, uint32_t offset); diff --git a/lib/env_dpdk/pci.c b/lib/env_dpdk/pci.c index 5b96704fb6..25dbd15eed 100644 --- a/lib/env_dpdk/pci.c +++ b/lib/env_dpdk/pci.c @@ -246,6 +246,61 @@ static struct rte_driver g_ioat_drv = { PMD_REGISTER_DRIVER(g_ioat_drv, spdk_ioat); #endif +static struct spdk_pci_enum_ctx * +spdk_pci_find_driver(enum spdk_pci_device_type type) +{ + if (type == SPDK_PCI_DEVICE_NVME) { + return &g_nvme_pci_drv; + } else if (type == SPDK_PCI_DEVICE_IOAT) { + return &g_ioat_pci_drv; + } else { + return NULL; + } +} + +void +spdk_pci_device_detach(struct spdk_pci_device *device) +{ + rte_eal_pci_detach(&device->addr); +} + +int +spdk_pci_device_attach(enum spdk_pci_device_type type, + spdk_pci_enum_cb enum_cb, + void *enum_ctx, struct spdk_pci_addr *pci_address) +{ + struct rte_pci_addr addr; + struct spdk_pci_enum_ctx *ctx; + + ctx = spdk_pci_find_driver(type); + if (ctx == NULL) { + return -1; + } + + addr.domain = pci_address->domain; + addr.bus = pci_address->bus; + addr.devid = pci_address->dev; + addr.function = pci_address->func; + + pthread_mutex_lock(&ctx->mtx); + + ctx->cb_fn = enum_cb; + ctx->cb_arg = enum_ctx; + + if (rte_eal_pci_probe_one(&addr) != 0) { + ctx->cb_arg = NULL; + ctx->cb_fn = NULL; + pthread_mutex_unlock(&ctx->mtx); + return -1; + } + + ctx->cb_arg = NULL; + ctx->cb_fn = NULL; + pthread_mutex_unlock(&ctx->mtx); + + return 0; +} + /* Note: You can call spdk_pci_enumerate from more than one thread * simultaneously safely, but you cannot call spdk_pci_enumerate * and rte_eal_pci_probe simultaneously. @@ -255,17 +310,12 @@ spdk_pci_enumerate(enum spdk_pci_device_type type, spdk_pci_enum_cb enum_cb, void *enum_ctx) { - struct spdk_pci_enum_ctx *ctx; + struct spdk_pci_enum_ctx *ctx = spdk_pci_find_driver(type); - if (type == SPDK_PCI_DEVICE_NVME) { - ctx = &g_nvme_pci_drv; - } else if (type == SPDK_PCI_DEVICE_IOAT) { - ctx = &g_ioat_pci_drv; - } else { + if (ctx == NULL) { return -1; } - pthread_mutex_lock(&ctx->mtx); ctx->cb_fn = enum_cb; diff --git a/lib/nvme/nvme_pcie.c b/lib/nvme/nvme_pcie.c index cfb09e264e..35059d96cf 100644 --- a/lib/nvme/nvme_pcie.c +++ b/lib/nvme/nvme_pcie.c @@ -578,6 +578,7 @@ nvme_pcie_ctrlr_destruct(struct spdk_nvme_ctrlr *ctrlr) } nvme_pcie_ctrlr_free_bars(pctrlr); + spdk_pci_device_detach(pctrlr->devhandle); spdk_free(pctrlr); return 0;