Signed-off-by: Dmitry Kalinkin <dmitry.kalin...@gmail.com>
Cc: Igor Alekseev <igor.aleks...@itep.ru>
---
 drivers/vme/bridges/vme_ca91cx42.c | 15 +++++++++++++--
 drivers/vme/bridges/vme_tsi148.c   | 15 +++++++++++++--
 2 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/drivers/vme/bridges/vme_ca91cx42.c 
b/drivers/vme/bridges/vme_ca91cx42.c
index 18078ec..ffb8e91 100644
--- a/drivers/vme/bridges/vme_ca91cx42.c
+++ b/drivers/vme/bridges/vme_ca91cx42.c
@@ -1192,7 +1192,7 @@ static int ca91cx42_dma_list_exec(struct vme_dma_list 
*list)
 {
        struct vme_dma_resource *ctrlr;
        struct ca91cx42_dma_entry *entry;
-       int retval = 0;
+       int retval;
        dma_addr_t bus_addr;
        u32 val;
        struct device *dev;
@@ -1245,9 +1245,19 @@ static int ca91cx42_dma_list_exec(struct vme_dma_list 
*list)
 
        iowrite32(val, bridge->base + DGCS);
 
-       wait_event_interruptible(bridge->dma_queue,
+       retval = wait_event_interruptible(bridge->dma_queue,
                ca91cx42_dma_busy(ctrlr->parent));
 
+       if (retval) {
+               val = ioread32(bridge->base + DGCS);
+               iowrite32(val | CA91CX42_DGCS_STOP_REQ, bridge->base + DGCS);
+               /* Wait for the operation to abort */
+               wait_event(bridge->dma_queue,
+                       ca91cx42_dma_busy(ctrlr->parent));
+               retval = -EINTR;
+               goto exit;
+       }
+
        /*
         * Read status register, this register is valid until we kick off a
         * new transfer.
@@ -1261,6 +1271,7 @@ static int ca91cx42_dma_list_exec(struct vme_dma_list 
*list)
                val = ioread32(bridge->base + DCTL);
        }
 
+exit:
        /* Remove list from running list */
        mutex_lock(&ctrlr->mtx);
        list_del(&list->list);
diff --git a/drivers/vme/bridges/vme_tsi148.c b/drivers/vme/bridges/vme_tsi148.c
index 03b0755..f6c455e 100644
--- a/drivers/vme/bridges/vme_tsi148.c
+++ b/drivers/vme/bridges/vme_tsi148.c
@@ -1892,7 +1892,7 @@ static int tsi148_dma_busy(struct vme_bridge 
*tsi148_bridge, int channel)
 static int tsi148_dma_list_exec(struct vme_dma_list *list)
 {
        struct vme_dma_resource *ctrlr;
-       int channel, retval = 0;
+       int channel, retval;
        struct tsi148_dma_entry *entry;
        u32 bus_addr_high, bus_addr_low;
        u32 val, dctlreg = 0;
@@ -1942,9 +1942,19 @@ static int tsi148_dma_list_exec(struct vme_dma_list 
*list)
        iowrite32be(dctlreg | TSI148_LCSR_DCTL_DGO, bridge->base +
                TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DCTL);
 
-       wait_event_interruptible(bridge->dma_queue[channel],
+       retval = wait_event_interruptible(bridge->dma_queue[channel],
                tsi148_dma_busy(ctrlr->parent, channel));
 
+       if (retval) {
+               iowrite32be(dctlreg | TSI148_LCSR_DCTL_ABT, bridge->base +
+                       TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DCTL);
+               /* Wait for the operation to abort */
+               wait_event(bridge->dma_queue[channel],
+                       tsi148_dma_busy(ctrlr->parent, channel));
+               retval = -EINTR;
+               goto exit;
+       }
+
        /*
         * Read status register, this register is valid until we kick off a
         * new transfer.
@@ -1957,6 +1967,7 @@ static int tsi148_dma_list_exec(struct vme_dma_list *list)
                retval = -EIO;
        }
 
+exit:
        /* Remove list from running list */
        mutex_lock(&ctrlr->mtx);
        list_del(&list->list);
-- 
1.8.3.1

_______________________________________________
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

Reply via email to