summaryrefslogtreecommitdiffstats
path: root/driver/int.c
diff options
context:
space:
mode:
Diffstat (limited to 'driver/int.c')
-rw-r--r--driver/int.c258
1 files changed, 0 insertions, 258 deletions
diff --git a/driver/int.c b/driver/int.c
deleted file mode 100644
index 5dbcb7f..0000000
--- a/driver/int.c
+++ /dev/null
@@ -1,258 +0,0 @@
-/**
- *
- * @file int.c
- * @author Guillermo Marcus
- * @date 2009-04-05
- * @brief Contains the interrupt handler.
- *
- */
-
-/*
- * Change History:
- *
- * $Log: not supported by cvs2svn $
- * Revision 1.7 2008-01-11 10:18:28 marcus
- * Modified interrupt mechanism. Added atomic functions and queues, to address race conditions. Removed unused interrupt code.
- *
- * Revision 1.6 2007-11-04 20:58:22 marcus
- * Added interrupt generator acknowledge.
- * Fixed wrong operator.
- *
- * Revision 1.5 2007-10-31 15:42:21 marcus
- * Added IG ack for testing, may be removed later.
- *
- * Revision 1.4 2007-07-17 13:15:56 marcus
- * Removed Tasklets.
- * Using newest map for the ABB interrupts.
- *
- * Revision 1.3 2007-07-05 15:30:30 marcus
- * Added support for both register maps of the ABB.
- *
- * Revision 1.2 2007-05-29 07:50:18 marcus
- * Split code into 2 files. May get merged in the future again....
- *
- * Revision 1.1 2007/03/01 16:57:43 marcus
- * Divided driver file to ease the interrupt hooks for the user of the driver.
- * Modified Makefile accordingly.
- *
- */
-
-#include <linux/version.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/list.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/cdev.h>
-#include <linux/wait.h>
-#include <linux/sched.h>
-#include <stdbool.h>
-
-#include "config.h"
-
-#include "compat.h"
-
-#include "pciDriver.h"
-
-#include "common.h"
-
-#include "int.h"
-
-/*
- * The ID between IRQ_SOURCE in irq_outstanding and the actual source is arbitrary.
- * Therefore, be careful when communicating with multiple implementations.
- */
-
-/* IRQ_SOURCES */
-#define ABB_IRQ_CH0 0
-#define ABB_IRQ_CH1 1
-#define ABB_IRQ_IG 2
-
-/* See ABB user’s guide, register definitions (3.1) */
-#define ABB_INT_ENABLE (0x0010 >> 2)
-#define ABB_INT_STAT (0x0008 >> 2)
-
-#define ABB_INT_CH1_TIMEOUT (1 << 4)
-#define ABB_INT_CH0_TIMEOUT (1 << 5)
-#define ABB_INT_IG (1 << 2)
-#define ABB_INT_CH0 (1 << 1) /* downstream */
-#define ABB_INT_CH1 (1) /* upstream */
-
-#define ABB_CH0_CTRL (108 >> 2)
-#define ABB_CH1_CTRL (72 >> 2)
-#define ABB_CH_RESET (0x0201000A)
-#define ABB_IG_CTRL (0x0080 >> 2)
-#define ABB_IG_ACK (0x00F0)
-
-/**
- *
- * If IRQ-handling is enabled, this function will be called from pcidriver_probe
- * to initialize the IRQ handling (maps the BARs)
- *
- */
-int pcidriver_probe_irq(pcidriver_privdata_t *privdata)
-{
- unsigned char int_pin, int_line;
- unsigned long bar_addr, bar_len, bar_flags;
- int i;
- int err;
-
- for (i = 0; i < 6; i++)
- privdata->bars_kmapped[i] = NULL;
-
- for (i = 0; i < 6; i++) {
- bar_addr = pci_resource_start(privdata->pdev, i);
- bar_len = pci_resource_len(privdata->pdev, i);
- bar_flags = pci_resource_flags(privdata->pdev, i);
-
- /* check if it is a valid BAR, skip if not */
- if ((bar_addr == 0) || (bar_len == 0))
- continue;
-
- /* Skip IO regions (map only mem regions) */
- if (bar_flags & IORESOURCE_IO)
- continue;
-
- /* Check if the region is available */
- if ((err = pci_request_region(privdata->pdev, i, NULL)) != 0) {
- mod_info( "Failed to request BAR memory region.\n" );
- return err;
- }
-
- /* Map it into kernel space. */
- /* For x86 this is just a dereference of the pointer, but that is
- * not portable. So we need to do the portable way. Thanks Joern!
- */
-
- /* respect the cacheable-bility of the region */
- if (bar_flags & IORESOURCE_PREFETCH)
- privdata->bars_kmapped[i] = ioremap(bar_addr, bar_len);
- else
- privdata->bars_kmapped[i] = ioremap_nocache(bar_addr, bar_len);
-
- /* check for error */
- if (privdata->bars_kmapped[i] == NULL) {
- mod_info( "Failed to remap BAR%d into kernel space.\n", i );
- return -EIO;
- }
- }
-
- /* Initialize the interrupt handler for this device */
- /* Initialize the wait queues */
- for (i = 0; i < PCIDRIVER_INT_MAXSOURCES; i++) {
- init_waitqueue_head(&(privdata->irq_queues[i]));
- atomic_set(&(privdata->irq_outstanding[i]), 0);
- }
-
- /* Initialize the irq config */
- if ((err = pci_read_config_byte(privdata->pdev, PCI_INTERRUPT_PIN, &int_pin)) != 0) {
- /* continue without interrupts */
- int_pin = 0;
- mod_info("Error getting the interrupt pin. Disabling interrupts for this device\n");
- }
-
- /* Disable interrupts and activate them if everything can be set up properly */
- privdata->irq_enabled = 0;
-
- if (int_pin == 0)
- return 0;
-
- if ((err = pci_read_config_byte(privdata->pdev, PCI_INTERRUPT_LINE, &int_line)) != 0) {
- mod_info("Error getting the interrupt line. Disabling interrupts for this device\n");
- return 0;
- }
-
- /* Enable interrupts using MSI mode */
- if (!pci_enable_msi(privdata->pdev))
- privdata->msi_mode = 1;
-
- /* register interrupt handler */
- if ((err = request_irq(privdata->pdev->irq, pcidriver_irq_handler, MODNAME, privdata)) != 0) {
- mod_info("Error registering the interrupt handler. Disabling interrupts for this device\n");
- return 0;
- }
-
- privdata->irq_enabled = 1;
- mod_info("Registered Interrupt Handler at pin %i, line %i, IRQ %i\n", int_pin, int_line, privdata->pdev->irq );
-
- return 0;
-}
-
-/**
- *
- * Frees/cleans up the data structures, called from pcidriver_remove()
- *
- */
-void pcidriver_remove_irq(pcidriver_privdata_t *privdata)
-{
- /* Release the IRQ handler */
- if (privdata->irq_enabled != 0)
- free_irq(privdata->pdev->irq, privdata);
-
- if (privdata->msi_mode) {
- pci_disable_msi(privdata->pdev);
- privdata->msi_mode = 0;
- }
-
- pcidriver_irq_unmap_bars(privdata);
-}
-
-/**
- *
- * Unmaps the BARs and releases them
- *
- */
-void pcidriver_irq_unmap_bars(pcidriver_privdata_t *privdata)
-{
- int i;
-
- for (i = 0; i < 6; i++) {
- if (privdata->bars_kmapped[i] == NULL)
- continue;
-
- iounmap((void*)privdata->bars_kmapped[i]);
- pci_release_region(privdata->pdev, i);
- }
-}
-
-/**
- *
- * Acknowledges the receival of an interrupt to the card.
- *
- * @returns true if the card was acknowledget
- * @returns false if the interrupt was not for one of our cards
- *
- * @see check_acknowlegde_channel
- *
- */
-static bool pcidriver_irq_acknowledge(pcidriver_privdata_t *privdata)
-{
- int channel = 0;
-// volatile unsigned int *bar;
-// bar = privdata->bars_kmapped[0];
-// mod_info_dbg("interrupt registers. ISR: %x, IER: %x\n", bar[ABB_INT_STAT], bar[ABB_INT_ENABLE]);
-
- atomic_inc(&(privdata->irq_outstanding[channel]));
- wake_up_interruptible(&(privdata->irq_queues[channel]));
-
- return true;
-}
-
-/**
- *
- * Handles IRQs. At the moment, this acknowledges the card that this IRQ
- * was received and then increases the driver's IRQ counter.
- *
- * @see pcidriver_irq_acknowledge
- *
- */
-IRQ_HANDLER_FUNC(pcidriver_irq_handler)
-{
- pcidriver_privdata_t *privdata = (pcidriver_privdata_t *)dev_id;
-
- if (!pcidriver_irq_acknowledge(privdata))
- return IRQ_NONE;
-
- privdata->irq_count++;
- return IRQ_HANDLED;
-}