From 4a39fdf798b4f8f6dadc7109f04587dced12b5a9 Mon Sep 17 00:00:00 2001 From: "Suren A. Chilingaryan" Date: Tue, 13 Nov 2012 15:58:41 +0100 Subject: DMA-independent IRQ functions --- cli.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++------- dma.c | 44 +++--------------------- pcilib.h | 1 + 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 - Clean IRQ queue\n" +" --wait-irq - Wait for IRQ\n" + " DMA Modes:\n" " --start-dma [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 - List buffers for specified DMA engine\n" " --read-dma-buffer - Read the specified buffer\n" -" --wait-irq - 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 - 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 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 of kernel buffer in bytes (default: page)\n" -" -s - Number of buffers to allocate (default: 1)\n" -" --allignment - Buffer alignment (default: page)\n" "\n" " Addressing:\n" " -d - 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 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 of kernel buffer in bytes (default: page)\n" +" -s - Number of buffers to allocate (default: 1)\n" +" --allignment - 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 { -- cgit v1.2.3