dmatest: Fix NULL pointer dereference on ioat
authorJon Mason <jon.mason@intel.com>
Sun, 11 Nov 2012 23:03:20 +0000 (23:03 +0000)
committerVinod Koul <vinod.koul@intel.com>
Tue, 8 Jan 2013 06:05:05 +0000 (22:05 -0800)
device_control is an optional and not implemented in all DMA drivers.
Any calls to these will result in a NULL pointer dereference.  dmatest
makes two of these calls when completing the kernel thread and removing
the module.  These are corrected by calling the dmaengine_device_control
wrapper and checking for a non-existant device_control function pointer
there.

Signed-off-by: Jon Mason <jon.mason@intel.com>
CC: Vinod Koul <vinod.koul@intel.com>
CC: Dan Williams <djbw@fb.com>
Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
drivers/dma/dmatest.c
include/linux/dmaengine.h

index 3a8047b1f108aba1bd43e5d44ce8466f12ac6497..99a75e5d66be4a5a0bfe12f8a9b51a51fe9805e1 100644 (file)
@@ -536,7 +536,7 @@ err_srcs:
                        thread_name, total_tests, failed_tests, ret);
 
        /* terminate all transfers on specified channels */
-       chan->device->device_control(chan, DMA_TERMINATE_ALL, 0);
+       dmaengine_terminate_all(chan);
        if (iterations > 0)
                while (!kthread_should_stop()) {
                        DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wait_dmatest_exit);
@@ -561,7 +561,7 @@ static void dmatest_cleanup_channel(struct dmatest_chan *dtc)
        }
 
        /* terminate all transfers on specified channels */
-       dtc->chan->device->device_control(dtc->chan, DMA_TERMINATE_ALL, 0);
+       dmaengine_terminate_all(dtc->chan);
 
        kfree(dtc);
 }
index 3aa76dbed166f2b2c129fc3b153ae9d1e791d63e..be6e95395b1159670ca16f325b2fd7e0f540dc26 100644 (file)
@@ -608,7 +608,10 @@ static inline int dmaengine_device_control(struct dma_chan *chan,
                                           enum dma_ctrl_cmd cmd,
                                           unsigned long arg)
 {
-       return chan->device->device_control(chan, cmd, arg);
+       if (chan->device->device_control)
+               return chan->device->device_control(chan, cmd, arg);
+       else
+               return -ENOSYS;
 }
 
 static inline int dmaengine_slave_config(struct dma_chan *chan,