summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorroot <root@iss-tomyspiel-l>2011-06-16 04:28:59 +0200
committerroot <root@iss-tomyspiel-l>2011-06-16 04:28:59 +0200
commit1aafef50177b850efda576259cb78d2df7d03259 (patch)
tree4ccf44b46983b652b741f7b92dd394c4dc600748
parent3215a87dbbce676aa434a6d5b4835e456dac3605 (diff)
downloadipecamera-1aafef50177b850efda576259cb78d2df7d03259.tar.gz
ipecamera-1aafef50177b850efda576259cb78d2df7d03259.tar.bz2
ipecamera-1aafef50177b850efda576259cb78d2df7d03259.tar.xz
ipecamera-1aafef50177b850efda576259cb78d2df7d03259.zip
A bit of DMA infrastructure
-rw-r--r--cli.c52
-rw-r--r--driver/base.h2
-rw-r--r--driver/ioctl.c4
-rw-r--r--driver/pciDriver.h4
-rw-r--r--pci.c40
-rw-r--r--pci.h13
-rw-r--r--pcilib.h35
7 files changed, 126 insertions, 24 deletions
diff --git a/cli.c b/cli.c
index 73449ee..4a5aafc 100644
--- a/cli.c
+++ b/cli.c
@@ -167,8 +167,10 @@ void List(pcilib_t *handle, pcilib_model_t model, const char *bank) {
int i;
pcilib_register_bank_description_t *banks;
pcilib_register_description_t *registers;
+ pcilib_event_description_t *events;
- const pci_board_info *board_info = pcilib_get_board_info(handle);
+ const pcilib_board_info_t *board_info = pcilib_get_board_info(handle);
+ const pcilib_dma_info_t *dma_info = pcilib_get_dma_info(handle);
for (i = 0; i < PCILIB_MAX_BANKS; i++) {
if (board_info->bar_length[i] > 0) {
@@ -188,6 +190,36 @@ void List(pcilib_t *handle, pcilib_model_t model, const char *bank) {
}
}
printf("\n");
+
+ if ((dma_info)&&(dma_info->engines)) {
+ printf("DMA Engines: \n");
+ for (i = 0; dma_info->engines[i]; i++) {
+ pcilib_dma_engine_description_t *engine = dma_info->engines[i];
+ printf(" DMA %2d ", engine->addr);
+ switch (engine->direction) {
+ case PCILIB_DMA_FROM_DEVICE:
+ printf("C2S");
+ break;
+ case PCILIB_DMA_TO_DEVICE:
+ printf("S2C");
+ break;
+ case PCILIB_DMA_BIDIRECTIONAL:
+ printf("BI ");
+ break;
+ }
+ printf(" - Type: ");
+ switch (engine->type) {
+ case PCILIB_DMA_TYPE_BLOCK:
+ printf("Block");
+ break;
+ case PCILIB_DMA_TYPE_PACKET:
+ printf("Packet");
+ break;
+ }
+
+ printf(", Size: %08lx", engine->max_bytes);
+ }
+ }
if ((bank)&&(bank != (char*)-1)) banks = NULL;
else banks = pcilib_model[model].banks;
@@ -239,10 +271,24 @@ void List(pcilib_t *handle, pcilib_model_t model, const char *bank) {
}
printf("\n");
}
+
+ if (bank == (char*)-1) events = NULL;
+ else events = pcilib_model[model].events;
+
+ if (events) {
+ printf("Events: \n");
+ for (i = 0; events[i].name; i++) {
+ printf(" %s", events[i].name);
+ if ((events[i].description)&&(events[i].description[0])) {
+ printf(": %s", events[i].description);
+ }
+ }
+ printf("\n");
+ }
}
void Info(pcilib_t *handle, pcilib_model_t model) {
- const pci_board_info *board_info = pcilib_get_board_info(handle);
+ const pcilib_board_info_t *board_info = pcilib_get_board_info(handle);
printf("Vendor: %x, Device: %x, Interrupt Pin: %i, Interrupt Line: %i\n", board_info->vendor_id, board_info->device_id, board_info->interrupt_pin, board_info->interrupt_line);
List(handle, model, (char*)-1);
@@ -257,7 +303,7 @@ int Benchmark(pcilib_t *handle, pcilib_bar_t bar) {
unsigned long time;
unsigned int size, max_size;
- const pci_board_info *board_info = pcilib_get_board_info(handle);
+ const pcilib_board_info_t *board_info = pcilib_get_board_info(handle);
if (bar < 0) {
unsigned long maxlength = 0;
diff --git a/driver/base.h b/driver/base.h
index 743eee5..84f0aad 100644
--- a/driver/base.h
+++ b/driver/base.h
@@ -53,7 +53,7 @@ static const __devinitdata struct pci_device_id pcidriver_ids[] = {
/* prototypes for internal driver functions */
int pcidriver_pci_read( pcidriver_privdata_t *privdata, pci_cfg_cmd *pci_cmd );
int pcidriver_pci_write( pcidriver_privdata_t *privdata, pci_cfg_cmd *pci_cmd );
-int pcidriver_pci_info( pcidriver_privdata_t *privdata, pci_board_info *pci_info );
+int pcidriver_pci_info( pcidriver_privdata_t *privdata, pcilib_board_info_t *pci_info );
int pcidriver_mmap_pci( pcidriver_privdata_t *privdata, struct vm_area_struct *vmap , int bar );
int pcidriver_mmap_kmem( pcidriver_privdata_t *privdata, struct vm_area_struct *vmap );
diff --git a/driver/ioctl.c b/driver/ioctl.c
index 6240d31..dacf94a 100644
--- a/driver/ioctl.c
+++ b/driver/ioctl.c
@@ -143,7 +143,7 @@ static int ioctl_pci_info(pcidriver_privdata_t *privdata, unsigned long arg)
{
int ret;
int bar;
- READ_FROM_USER(pci_board_info, pci_info);
+ READ_FROM_USER(pcilib_board_info_t, pci_info);
pci_info.vendor_id = privdata->pdev->vendor;
pci_info.device_id = privdata->pdev->device;
@@ -163,7 +163,7 @@ static int ioctl_pci_info(pcidriver_privdata_t *privdata, unsigned long arg)
pci_info.bar_flags[bar] = pci_resource_flags(privdata->pdev, bar);
}
- WRITE_TO_USER(pci_board_info, pci_info);
+ WRITE_TO_USER(pcilib_board_info_t, pci_info);
return 0;
}
diff --git a/driver/pciDriver.h b/driver/pciDriver.h
index 083b0b2..98c1301 100644
--- a/driver/pciDriver.h
+++ b/driver/pciDriver.h
@@ -152,7 +152,7 @@ typedef struct {
unsigned long bar_start[6];
unsigned long bar_length[6];
unsigned long bar_flags[6];
-} pci_board_info;
+} pcilib_board_info_t;
/* ioctl interface */
@@ -182,7 +182,7 @@ typedef struct {
/* And now, the methods to access the PCI configuration area */
#define PCIDRIVER_IOC_PCI_CFG_RD _IOWR( PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 10, pci_cfg_cmd * )
#define PCIDRIVER_IOC_PCI_CFG_WR _IOWR( PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 11, pci_cfg_cmd * )
-#define PCIDRIVER_IOC_PCI_INFO _IOWR( PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 12, pci_board_info * )
+#define PCIDRIVER_IOC_PCI_INFO _IOWR( PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 12, pcilib_board_info_t * )
/* Clear interrupt queues */
#define PCIDRIVER_IOC_CLEAR_IOQ _IO( PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 13 )
diff --git a/pci.c b/pci.c
index 6221ddf..f40b9ed 100644
--- a/pci.c
+++ b/pci.c
@@ -31,7 +31,8 @@ struct pcilib_s {
int handle;
uintptr_t page_mask;
- pci_board_info board_info;
+ pcilib_board_info_t board_info;
+ pcilib_dma_info_t dma_info;
pcilib_model_t model;
char *bar_space[PCILIB_MAX_BANKS];
@@ -45,7 +46,10 @@ struct pcilib_s {
// char *data_space;
// size_t data_size;
- void *event_ctx;
+
+ pcilib_dma_context_t *dma_ctx;
+
+ pcilib_event_context_t *event_ctx;
#ifdef PCILIB_FILE_IO
int file_io_handle;
@@ -96,7 +100,7 @@ pcilib_t *pcilib_open(const char *device, pcilib_model_t model) {
return ctx;
}
-const pci_board_info *pcilib_get_board_info(pcilib_t *ctx) {
+const pcilib_board_info_t *pcilib_get_board_info(pcilib_t *ctx) {
int ret;
if (ctx->page_mask == (uintptr_t)-1) {
@@ -112,6 +116,18 @@ const pci_board_info *pcilib_get_board_info(pcilib_t *ctx) {
return &ctx->board_info;
}
+const pcilib_dma_info_t *pcilib_get_dma_info(pcilib_t *ctx) {
+ if (!ctx->dma_ctx) {
+ pcilib_model_t model = pcilib_get_model(ctx);
+ pcilib_dma_api_description_t *api = pcilib_model[model].dma_api;
+ if ((api)&&(api->init)) ctx->dma_ctx = api->init(ctx);
+
+ if (!ctx->dma_ctx) return NULL;
+ }
+
+ return &ctx->dma_info;
+}
+
pcilib_context_t *pcilib_get_implementation_context(pcilib_t *ctx) {
return ctx->event_ctx;
}
@@ -123,7 +139,7 @@ pcilib_model_t pcilib_get_model(pcilib_t *ctx) {
//return PCILIB_MODEL_PCI;
- const pci_board_info *board_info = pcilib_get_board_info(ctx);
+ const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx);
if (!board_info) return PCILIB_MODEL_PCI;
if ((board_info->vendor_id == PCIE_XILINX_VENDOR_ID)&&(board_info->device_id == PCIE_IPECAMERA_DEVICE_ID))
@@ -138,7 +154,7 @@ pcilib_model_t pcilib_get_model(pcilib_t *ctx) {
static pcilib_bar_t pcilib_detect_bar(pcilib_t *ctx, uintptr_t addr, size_t size) {
pcilib_bar_t i;
- const pci_board_info *board_info = pcilib_get_board_info(ctx);
+ const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx);
if (!board_info) return PCILIB_BAR_INVALID;
for (i = 0; i < PCILIB_MAX_BANKS; i++) {
@@ -149,7 +165,7 @@ static pcilib_bar_t pcilib_detect_bar(pcilib_t *ctx, uintptr_t addr, size_t size
}
static int pcilib_detect_address(pcilib_t *ctx, pcilib_bar_t *bar, uintptr_t *addr, size_t size) {
- const pci_board_info *board_info = pcilib_get_board_info(ctx);
+ const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx);
if (!board_info) return PCILIB_ERROR_NOTFOUND;
if (*bar == PCILIB_BAR_DETECT) {
@@ -179,7 +195,7 @@ void *pcilib_map_bar(pcilib_t *ctx, pcilib_bar_t bar) {
void *res;
int ret;
- const pci_board_info *board_info = pcilib_get_board_info(ctx);
+ const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx);
if (!board_info) return NULL;
if (ctx->bar_space[bar]) return ctx->bar_space[bar];
@@ -212,7 +228,7 @@ void *pcilib_map_bar(pcilib_t *ctx, pcilib_bar_t bar) {
}
void pcilib_unmap_bar(pcilib_t *ctx, pcilib_bar_t bar, void *data) {
- const pci_board_info *board_info = pcilib_get_board_info(ctx);
+ const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx);
if (!board_info) return;
if (ctx->bar_space[bar]) return;
@@ -396,7 +412,7 @@ static int pcilib_map_data_space(pcilib_t *ctx, uintptr_t addr) {
pcilib_bar_t i;
if (!ctx->data_bar_mapped) {
- const pci_board_info *board_info = pcilib_get_board_info(ctx);
+ const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx);
if (!board_info) return PCILIB_ERROR_FAILED;
err = pcilib_map_register_space(ctx);
@@ -511,9 +527,11 @@ void pcilib_close(pcilib_t *ctx) {
if (ctx) {
pcilib_model_t model = pcilib_get_model(ctx);
- pcilib_event_api_description_t *api = pcilib_model[model].event_api;
+ pcilib_event_api_description_t *eapi = pcilib_model[model].event_api;
+ pcilib_dma_api_description_t *dapi = pcilib_model[model].dma_api;
- if ((api)&&(api->free)) api->free(ctx->event_ctx);
+ if ((eapi)&&(eapi->free)) eapi->free(ctx->event_ctx);
+ if ((dapi)&&(dapi->free)) dapi->free(ctx->dma_ctx);
for (i = 0; i < PCILIB_MAX_BANKS; i++) {
if (ctx->bar_space[i]) {
diff --git a/pci.h b/pci.h
index e3e5c9a..0a7a55e 100644
--- a/pci.h
+++ b/pci.h
@@ -5,19 +5,24 @@
#include "driver/pciDriver.h"
+
+typedef void pcilib_event_context_t;
+typedef void pcilib_dma_context_t;
+
#include "pcilib.h"
-const pci_board_info *pcilib_get_board_info(pcilib_t *ctx);
+const pcilib_board_info_t *pcilib_get_board_info(pcilib_t *ctx);
+const pcilib_dma_info_t *pcilib_get_dma_info(pcilib_t *ctx);
#ifdef _PCILIB_PCI_C
# include "ipecamera/model.h"
# include "default.h"
pcilib_model_description_t pcilib_model[3] = {
- { 4, PCILIB_HOST_ENDIAN, NULL, NULL, NULL, NULL },
- { 4, PCILIB_HOST_ENDIAN, NULL, NULL, NULL, NULL },
- { 4, PCILIB_BIG_ENDIAN, ipecamera_registers, ipecamera_register_banks, ipecamera_register_ranges, ipecamera_events, &ipecamera_image_api }
+ { 4, PCILIB_HOST_ENDIAN, NULL, NULL, NULL, NULL, NULL },
+ { 4, PCILIB_HOST_ENDIAN, NULL, NULL, NULL, NULL, NULL },
+ { 4, PCILIB_BIG_ENDIAN, ipecamera_registers, ipecamera_register_banks, ipecamera_register_ranges, ipecamera_events, NULL, &ipecamera_image_api }
};
pcilib_protocol_description_t pcilib_protocol[3] = {
diff --git a/pcilib.h b/pcilib.h
index 1df65f6..6d52714 100644
--- a/pcilib.h
+++ b/pcilib.h
@@ -27,6 +27,9 @@ typedef uint8_t pcilib_register_bank_addr_t; /**< Type holding the register bank
typedef uint8_t pcilib_register_size_t; /**< Type holding the size in bits of the register */
typedef uint32_t pcilib_register_value_t; /**< Type holding the register value */
typedef uint64_t pcilib_event_id_t;
+typedef uint8_t pcilib_dma_addr_t;
+typedef uint8_t pcilib_dma_t;
+
typedef uint32_t pcilib_event_t;
@@ -128,10 +131,39 @@ typedef struct {
int (*write)(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, uint8_t bits, pcilib_register_value_t value);
} pcilib_protocol_description_t;
+typedef enum {
+ PCILIB_DMA_FROM_DEVICE = 1,
+ PCILIB_DMA_TO_DEVICE = 2,
+ PCILIB_DMA_BIDIRECTIONAL = 3
+} pcilib_dma_direction_t;
+
+typedef enum {
+ PCILIB_DMA_TYPE_BLOCK,
+ PCILIB_DMA_TYPE_PACKET
+} pcilib_dma_type_t;
+
+typedef struct {
+ pcilib_dma_addr_t addr;
+ pcilib_dma_type_t type;
+ pcilib_dma_direction_t direction;
+ size_t max_bytes;
+} pcilib_dma_engine_description_t;
+
+typedef struct {
+ pcilib_dma_engine_description_t **engines;
+} pcilib_dma_info_t;
typedef int (*pcilib_callback_t)(pcilib_event_t event, pcilib_event_id_t event_id, void *user);
typedef struct {
+ pcilib_dma_context_t *(*init)(pcilib_t *ctx);
+ void (*free)(pcilib_dma_context_t *ctx);
+
+// int (*read)(pcilib_dma_context_t *ctx, pcilib_event_t event_mask, pcilib_callback_t callback, void *user);
+// int (*write)(pcilib_dma_context_t *ctx);
+} pcilib_dma_api_description_t;
+
+typedef struct {
pcilib_context_t *(*init)(pcilib_t *ctx);
void (*free)(pcilib_context_t *ctx);
@@ -154,7 +186,8 @@ typedef struct {
pcilib_register_bank_description_t *banks;
pcilib_register_range_t *ranges;
pcilib_event_description_t *events;
-
+
+ pcilib_dma_api_description_t *dma_api;
pcilib_event_api_description_t *event_api;
} pcilib_model_description_t;