summaryrefslogtreecommitdiffstats
path: root/pcilib
diff options
context:
space:
mode:
Diffstat (limited to 'pcilib')
-rw-r--r--pcilib/pci.c49
-rw-r--r--pcilib/pci.h5
2 files changed, 52 insertions, 2 deletions
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);