From 46754246bddd1c15d61e915bd860448bab8d7400 Mon Sep 17 00:00:00 2001 From: "Suren A. Chilingaryan" Date: Thu, 19 Nov 2015 02:21:30 +0100 Subject: Driver versioning --- pcilib/pci.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- pcilib/pci.h | 5 +++++ 2 files changed, 52 insertions(+), 2 deletions(-) (limited to 'pcilib') diff --git a/pcilib/pci.c b/pcilib/pci.c index e45aaba..26dfdbf 100644 --- a/pcilib/pci.c +++ b/pcilib/pci.c @@ -108,6 +108,7 @@ static int pcilib_detect_model(pcilib_t *ctx, const char *model) { pcilib_t *pcilib_open(const char *device, const char *model) { int err, xmlerr; pcilib_t *ctx = malloc(sizeof(pcilib_t)); + const pcilib_driver_version_t *drv_version; if (!model) model = getenv("PCILIB_MODEL"); @@ -123,6 +124,13 @@ pcilib_t *pcilib_open(const char *device, const char *model) { return NULL; } + drv_version = pcilib_get_driver_version(ctx); + if (!drv_version) { + pcilib_error("Driver verification has failed (%s)", device); + free(ctx); + return NULL; + } + ctx->page_mask = (uintptr_t)-1; if ((model)&&(!strcasecmp(model, "maintenance"))) { @@ -224,6 +232,34 @@ pcilib_t *pcilib_open(const char *device, const char *model) { } +const pcilib_driver_version_t *pcilib_get_driver_version(pcilib_t *ctx) { + int ret; + + if (!ctx->driver_version.version) { + ret = ioctl( ctx->handle, PCIDRIVER_IOC_VERSION, &ctx->driver_version ); + if (ret) { + pcilib_error("PCIDRIVER_IOC_DRIVER_VERSION ioctl have failed"); + return NULL; + } + + if (ctx->driver_version.interface != PCIDRIVER_INTERFACE_VERSION) { + pcilib_error("Using pcilib (version: %u.%u.%u, driver interface: 0x%lx) with incompatible driver (version: %u.%u.%u, interface: 0x%lx)", + PCILIB_VERSION_GET_MAJOR(PCILIB_VERSION), + PCILIB_VERSION_GET_MINOR(PCILIB_VERSION), + PCILIB_VERSION_GET_MICRO(PCILIB_VERSION), + PCIDRIVER_INTERFACE_VERSION, + PCILIB_VERSION_GET_MAJOR(ctx->driver_version.version), + PCILIB_VERSION_GET_MINOR(ctx->driver_version.version), + PCILIB_VERSION_GET_MICRO(ctx->driver_version.version), + ctx->driver_version.interface + ); + return NULL; + } + } + + return &ctx->driver_version; +} + const pcilib_board_info_t *pcilib_get_board_info(pcilib_t *ctx) { int ret; @@ -236,7 +272,7 @@ const pcilib_board_info_t *pcilib_get_board_info(pcilib_t *ctx) { ctx->page_mask = pcilib_get_page_mask(); } - + return &ctx->board_info; } @@ -432,8 +468,17 @@ const pcilib_pcie_link_info_t *pcilib_get_pcie_link_info(pcilib_t *ctx) { return &ctx->link_info; } +int pcilib_get_device_state(pcilib_t *ctx, pcilib_device_state_t *state) { + int ret = ioctl( ctx->handle, PCIDRIVER_IOC_DEVICE_STATE, state); + if (ret < 0) { + pcilib_error("PCIDRIVER_IOC_DEVICE_STATE ioctl have failed"); + return PCILIB_ERROR_FAILED; + } + return 0; +} + int pcilib_set_dma_mask(pcilib_t *ctx, int mask) { - if (ioctl( ctx->handle, PCIDRIVER_IOC_SET_DMA_MASK, mask ) < 0) + if (ioctl(ctx->handle, PCIDRIVER_IOC_DMA_MASK, mask) < 0) return PCILIB_ERROR_FAILED; return 0; diff --git a/pcilib/pci.h b/pcilib/pci.h index bf977fc..b81d295 100644 --- a/pcilib/pci.h +++ b/pcilib/pci.h @@ -48,6 +48,7 @@ struct pcilib_s { int handle; /**< file handle of device */ uintptr_t page_mask; /**< Selects bits which define offset within the page */ + pcilib_driver_version_t driver_version; /**< Version reported by the driver */ pcilib_board_info_t board_info; /**< The mandatory information about board as defined by PCI specification */ pcilib_pcie_link_info_t link_info; /**< Infomation about PCIe connection */ char *bar_space[PCILIB_MAX_BARS]; /**< Pointers to the mapped BARs in virtual address space */ @@ -112,8 +113,12 @@ extern "C" { #endif pcilib_context_t *pcilib_get_implementation_context(pcilib_t *ctx); + +const pcilib_driver_version_t *pcilib_get_driver_version(pcilib_t *ctx); const pcilib_board_info_t *pcilib_get_board_info(pcilib_t *ctx); const pcilib_pcie_link_info_t *pcilib_get_pcie_link_info(pcilib_t *ctx); +int pcilib_get_device_state(pcilib_t *ctx, pcilib_device_state_t *state); + int pcilib_map_register_space(pcilib_t *ctx); int pcilib_map_data_space(pcilib_t *ctx, uintptr_t addr); -- cgit v1.2.3