summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuren A. Chilingaryan <csa@dside.dyndns.org>2012-11-13 15:58:41 +0100
committerSuren A. Chilingaryan <csa@dside.dyndns.org>2012-11-13 15:58:41 +0100
commit4a39fdf798b4f8f6dadc7109f04587dced12b5a9 (patch)
treea7884cae8cc77c4d173d98e661c3ab64c6f43699
parent67cd67b13eeefb8b89fc7448f8dad176897c8f7b (diff)
downloadpcitool-4a39fdf798b4f8f6dadc7109f04587dced12b5a9.tar.gz
pcitool-4a39fdf798b4f8f6dadc7109f04587dced12b5a9.tar.bz2
pcitool-4a39fdf798b4f8f6dadc7109f04587dced12b5a9.tar.xz
pcitool-4a39fdf798b4f8f6dadc7109f04587dced12b5a9.zip
DMA-independent IRQ functions
-rw-r--r--cli.c118
-rw-r--r--dma.c44
-rw-r--r--pcilib.h1
3 files changed, 112 insertions, 51 deletions
diff --git a/cli.c b/cli.c
index aeb5918..4bff445 100644
--- a/cli.c
+++ b/cli.c
@@ -76,6 +76,9 @@ typedef enum {
MODE_LIST_DMA,
MODE_LIST_DMA_BUFFERS,
MODE_READ_DMA_BUFFER,
+ MODE_ENABLE_IRQ,
+ MODE_DISABLE_IRQ,
+ MODE_ACK_IRQ,
MODE_WAIT_IRQ,
MODE_ALLOC_KMEM,
MODE_LIST_KMEM,
@@ -141,6 +144,9 @@ typedef enum {
OPT_READ_DMA_BUFFER,
OPT_START_DMA,
OPT_STOP_DMA,
+ OPT_ENABLE_IRQ,
+ OPT_DISABLE_IRQ,
+ OPT_ACK_IRQ,
OPT_WAIT_IRQ,
OPT_ITERATIONS,
OPT_ALLOC_KMEM,
@@ -188,6 +194,9 @@ static struct option long_options[] = {
{"list-dma-engines", no_argument, 0, OPT_LIST_DMA },
{"list-dma-buffers", required_argument, 0, OPT_LIST_DMA_BUFFERS },
{"read-dma-buffer", required_argument, 0, OPT_READ_DMA_BUFFER },
+ {"enable-irq", optional_argument, 0, OPT_ENABLE_IRQ },
+ {"disable-irq", optional_argument, 0, OPT_DISABLE_IRQ },
+ {"acknowledge-irq", optional_argument, 0, OPT_ACK_IRQ },
{"wait-irq", optional_argument, 0, OPT_WAIT_IRQ },
{"list-kernel-memory", optional_argument, 0, OPT_LIST_KMEM },
{"read-kernel-memory", required_argument, 0, OPT_READ_KMEM },
@@ -237,13 +246,18 @@ void Usage(int argc, char *argv[], const char *format, ...) {
" --trigger [event] - Trigger Events\n"
" -g [event] - Grab Events\n"
"\n"
+" IRQ Modes:\n"
+" --enable-irq [type] - Enable IRQs\n"
+" --disable-irq [type] - Disable IRQs\n"
+" --acknowledge-irq <source> - Clean IRQ queue\n"
+" --wait-irq <source> - Wait for IRQ\n"
+
" DMA Modes:\n"
" --start-dma <num>[r|w] - Start specified DMA engine\n"
" --stop-dma [num[r|w]] - Stop specified engine or DMA subsystem\n"
" --list-dma-engines - List active DMA engines\n"
" --list-dma-buffers <dma> - List buffers for specified DMA engine\n"
" --read-dma-buffer <dma:buf> - Read the specified buffer\n"
-" --wait-irq <source> - Wait for IRQ\n"
"\n"
" Kernel Modes:\n"
" --list-kernel-memory [use] - List kernel buffers\n"
@@ -253,13 +267,6 @@ void Usage(int argc, char *argv[], const char *format, ...) {
" --free-kernel-memory <use> - Cleans lost kernel space buffers (DANGEROUS)\n"
" dma - Remove all buffers allocated by DMA subsystem\n"
" #number - Remove all buffers with the specified use id\n"
-" --type <type> - Type of kernel memory to allocate\n"
-" consistent - Consistent memory\n"
-" s2c - DMA S2C (write) memory\n"
-" c2s - DMA C2S (read) memory\n"
-" --page-size <size> - Size of kernel buffer in bytes (default: page)\n"
-" -s <size> - Number of buffers to allocate (default: 1)\n"
-" --allignment <alignment> - Buffer alignment (default: page)\n"
"\n"
" Addressing:\n"
" -d <device> - FPGA device (/dev/fpga0)\n"
@@ -297,6 +304,15 @@ void Usage(int argc, char *argv[], const char *format, ...) {
" --multipacket - Read multiple packets\n"
" --wait - Wait until data arrives\n"
"\n"
+" Kernel Options:\n"
+" --type <type> - Type of kernel memory to allocate\n"
+" consistent - Consistent memory\n"
+" s2c - DMA S2C (write) memory\n"
+" c2s - DMA C2S (read) memory\n"
+" --page-size <size> - Size of kernel buffer in bytes (default: page)\n"
+" -s <size> - Number of buffers to allocate (default: 1)\n"
+" --allignment <alignment> - Buffer alignment (default: page)\n"
+"\n"
" Information:\n"
" --verbose [level] - Announce details of ongoing operations\n"
" -q - Quiete mode (suppress warnings)\n"
@@ -2235,16 +2251,38 @@ int ReadBuffer(pcilib_t *handle, const char *device, pcilib_model_description_t
}
+int EnableIRQ(pcilib_t *handle, pcilib_model_description_t *model_info, pcilib_irq_type_t irq_type) {
+ int err;
-int WaitIRQ(pcilib_t *handle, pcilib_model_description_t *model_info, pcilib_irq_hw_source_t irq_source, pcilib_timeout_t timeout) {
+ err = pcilib_enable_irq(handle, irq_type, 0);
+ if (err) {
+ if ((err != PCILIB_ERROR_NOTSUPPORTED)&&(err != PCILIB_ERROR_NOTAVAILABLE))
+ Error("Error enabling IRQs");
+ }
+
+ return err;
+}
+
+int DisableIRQ(pcilib_t *handle, pcilib_model_description_t *model_info, pcilib_irq_type_t irq_type) {
int err;
- size_t count;
- err = pcilib_enable_irq(handle, PCILIB_EVENT_IRQ, 0);
+ err = pcilib_disable_irq(handle, 0);
if (err) {
if ((err != PCILIB_ERROR_NOTSUPPORTED)&&(err != PCILIB_ERROR_NOTAVAILABLE))
- Error("Error enabling IRQs");
+ Error("Error disabling IRQs");
}
+
+ return err;
+}
+
+int AckIRQ(pcilib_t *handle, pcilib_model_description_t *model_info, pcilib_irq_hw_source_t irq_source) {
+ pcilib_clear_irq(handle, irq_source);
+ return 0;
+}
+
+int WaitIRQ(pcilib_t *handle, pcilib_model_description_t *model_info, pcilib_irq_hw_source_t irq_source, pcilib_timeout_t timeout) {
+ int err;
+ size_t count;
err = pcilib_wait_irq(handle, irq_source, timeout, &count);
if (err) {
@@ -2297,6 +2335,7 @@ int main(int argc, char **argv) {
const char *use = NULL;
pcilib_kmem_use_t use_id = 0;
size_t block = (size_t)-1;
+ pcilib_irq_type_t irq_type = PCILIB_IRQ_TYPE_ALL;
pcilib_irq_hw_source_t irq_source = PCILIB_IRQ_SOURCE_DEFAULT;
pcilib_dma_direction_t dma_direction = PCILIB_DMA_BIDIRECTIONAL;
@@ -2435,6 +2474,51 @@ int main(int argc, char **argv) {
if (optarg) dma_channel = optarg;
else if ((optind < argc)&&(argv[optind][0] != '-')) dma_channel = argv[optind++];
break;
+ case OPT_ENABLE_IRQ:
+ if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
+
+ mode = MODE_ENABLE_IRQ;
+ if (optarg) num_offset = optarg;
+ else if ((optind < argc)&&(argv[optind][0] != '-')) num_offset = argv[optind++];
+ else num_offset = NULL;
+
+ if (num_offset) {
+ if ((!isnumber(num_offset))||(sscanf(num_offset, "%li", &itmp) != 1))
+ Usage(argc, argv, "Invalid IRQ source is specified (%s)", num_offset);
+
+ irq_type = itmp;
+ }
+ break;
+ case OPT_DISABLE_IRQ:
+ if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
+
+ mode = MODE_DISABLE_IRQ;
+ if (optarg) num_offset = optarg;
+ else if ((optind < argc)&&(argv[optind][0] != '-')) num_offset = argv[optind++];
+ else num_offset = NULL;
+
+ if (num_offset) {
+ if ((!isnumber(num_offset))||(sscanf(num_offset, "%li", &itmp) != 1))
+ Usage(argc, argv, "Invalid IRQ source is specified (%s)", num_offset);
+
+ irq_type = itmp;
+ }
+ break;
+ case OPT_ACK_IRQ:
+ if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
+
+ mode = MODE_ACK_IRQ;
+ if (optarg) num_offset = optarg;
+ else if ((optind < argc)&&(argv[optind][0] != '-')) num_offset = argv[optind++];
+ else num_offset = NULL;
+
+ if (num_offset) {
+ if ((!isnumber(num_offset))||(sscanf(num_offset, "%li", &itmp) != 1))
+ Usage(argc, argv, "Invalid IRQ source is specified (%s)", num_offset);
+
+ irq_source = itmp;
+ }
+ break;
case OPT_WAIT_IRQ:
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
@@ -2456,6 +2540,7 @@ int main(int argc, char **argv) {
if (optarg) use = optarg;
else if ((optind < argc)&&(argv[optind][0] != '-')) use = argv[optind++];
+ else use = NULL;
if (use) {
num_offset = strchr(use, ':');
@@ -2927,6 +3012,15 @@ int main(int argc, char **argv) {
case MODE_STOP_DMA:
StartStopDMA(handle, model_info, dma, dma_direction, 0);
break;
+ case MODE_ENABLE_IRQ:
+ EnableIRQ(handle, model_info, irq_type);
+ break;
+ case MODE_DISABLE_IRQ:
+ DisableIRQ(handle, model_info, irq_type);
+ break;
+ case MODE_ACK_IRQ:
+ AckIRQ(handle, model_info, irq_source);
+ break;
case MODE_WAIT_IRQ:
WaitIRQ(handle, model_info, irq_source, timeout);
break;
diff --git a/dma.c b/dma.c
index c65bad6..e3bc77c 100644
--- a/dma.c
+++ b/dma.c
@@ -80,6 +80,7 @@ int pcilib_start_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t
int pcilib_stop_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags) {
const pcilib_dma_info_t *info = pcilib_get_dma_info(ctx);
+
if (!info) {
pcilib_error("DMA is not supported by the device");
return PCILIB_ERROR_NOTSUPPORTED;
@@ -99,63 +100,28 @@ int pcilib_stop_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t f
int pcilib_enable_irq(pcilib_t *ctx, pcilib_irq_type_t irq_type, pcilib_dma_flags_t flags) {
const pcilib_dma_info_t *info = pcilib_get_dma_info(ctx);
- if (!info) {
- //pcilib_error("DMA is not supported by the device");
- return PCILIB_ERROR_NOTSUPPORTED;
- }
- if (!ctx->model_info.dma_api) {
- //pcilib_error("DMA Engine is not configured in the current model");
- return PCILIB_ERROR_NOTAVAILABLE;
- }
-
- if (!ctx->model_info.dma_api->enable_irq) {
- return 0;
- }
+ if ((!info)||(!ctx->model_info.dma_api)||(!ctx->model_info.dma_api->enable_irq)) return 0;
return ctx->model_info.dma_api->enable_irq(ctx->dma_ctx, irq_type, flags);
}
int pcilib_disable_irq(pcilib_t *ctx, pcilib_dma_flags_t flags) {
const pcilib_dma_info_t *info = pcilib_get_dma_info(ctx);
- if (!info) {
- pcilib_error("DMA is not supported by the device");
- return PCILIB_ERROR_NOTSUPPORTED;
- }
- if (!ctx->model_info.dma_api) {
- pcilib_error("DMA Engine is not configured in the current model");
- return PCILIB_ERROR_NOTAVAILABLE;
- }
-
- if (!ctx->model_info.dma_api->disable_irq) {
- return 0;
- }
-
+ if ((!info)||(!ctx->model_info.dma_api)||(!ctx->model_info.dma_api->disable_irq)) return 0;
+
return ctx->model_info.dma_api->disable_irq(ctx->dma_ctx, flags);
}
int pcilib_acknowledge_irq(pcilib_t *ctx, pcilib_irq_type_t irq_type, pcilib_irq_source_t irq_source) {
const pcilib_dma_info_t *info = pcilib_get_dma_info(ctx);
- if (!info) {
- pcilib_error("DMA is not supported by the device");
- return PCILIB_ERROR_NOTSUPPORTED;
- }
- if (!ctx->model_info.dma_api) {
- pcilib_error("DMA Engine is not configured in the current model");
- return PCILIB_ERROR_NOTAVAILABLE;
- }
-
- if (!ctx->model_info.dma_api->acknowledge_irq) {
- return 0;
- }
+ if ((!info)||(!ctx->model_info.dma_api)||(!ctx->model_info.dma_api->acknowledge_irq)) return 0;
return ctx->model_info.dma_api->acknowledge_irq(ctx->dma_ctx, irq_type, irq_source);
}
-
-
typedef struct {
size_t size;
void *data;
diff --git a/pcilib.h b/pcilib.h
index 0547461..dfe4b6c 100644
--- a/pcilib.h
+++ b/pcilib.h
@@ -128,6 +128,7 @@ typedef enum {
#define PCILIB_EVENT_DATA_TYPE_INVALID ((pcilib_event_data_type_t)-1)
#define PCILIB_TIMEOUT_INFINITE ((pcilib_timeout_t)-1)
#define PCILIB_TIMEOUT_IMMEDIATE 0
+#define PCILIB_IRQ_TYPE_ALL 0
#define PCILIB_IRQ_SOURCE_DEFAULT 0
typedef struct {