[IA64] Don't go beyond iosapic_intr_info's arraysize
[safe/jmp/linux-2.6] / drivers / dma / ioat_dma.c
index f8396ca..b3759c4 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/workqueue.h>
+#include <linux/i7300_idle.h>
 #include "ioatdma.h"
 #include "ioatdma_registers.h"
 #include "ioatdma_hw.h"
@@ -171,8 +172,10 @@ static int ioat_dma_enumerate_channels(struct ioatdma_device *device)
        xfercap_scale = readb(device->reg_base + IOAT_XFERCAP_OFFSET);
        xfercap = (xfercap_scale == 0 ? -1 : (1UL << xfercap_scale));
 
-#if CONFIG_I7300_IDLE_IOAT_CHANNEL
-       device->common.chancnt--;
+#ifdef  CONFIG_I7300_IDLE_IOAT_CHANNEL
+       if (i7300_idle_platform_probe(NULL, NULL) == 0) {
+               device->common.chancnt--;
+       }
 #endif
        for (i = 0; i < device->common.chancnt; i++) {
                ioat_chan = kzalloc(sizeof(*ioat_chan), GFP_KERNEL);
@@ -522,7 +525,7 @@ static dma_cookie_t ioat1_tx_submit(struct dma_async_tx_descriptor *tx)
        }
 
        hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
-       if (new->async_tx.callback) {
+       if (first->async_tx.callback) {
                hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN;
                if (first != new) {
                        /* move callback into to last desc */
@@ -614,7 +617,7 @@ static dma_cookie_t ioat2_tx_submit(struct dma_async_tx_descriptor *tx)
        }
 
        hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
-       if (new->async_tx.callback) {
+       if (first->async_tx.callback) {
                hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN;
                if (first != new) {
                        /* move callback into to last desc */
@@ -731,8 +734,7 @@ static void ioat2_dma_massage_chan_desc(struct ioat_dma_chan *ioat_chan)
  * ioat_dma_alloc_chan_resources - returns the number of allocated descriptors
  * @chan: the channel to be filled out
  */
-static int ioat_dma_alloc_chan_resources(struct dma_chan *chan,
-                                        struct dma_client *client)
+static int ioat_dma_alloc_chan_resources(struct dma_chan *chan)
 {
        struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
        struct ioat_desc_sw *desc;
@@ -804,6 +806,12 @@ static void ioat_dma_free_chan_resources(struct dma_chan *chan)
        struct ioat_desc_sw *desc, *_desc;
        int in_use_descs = 0;
 
+       /* Before freeing channel resources first check
+        * if they have been previously allocated for this channel.
+        */
+       if (ioat_chan->desccount == 0)
+               return;
+
        tasklet_disable(&ioat_chan->cleanup_task);
        ioat_dma_memcpy_cleanup(ioat_chan);
 
@@ -866,6 +874,7 @@ static void ioat_dma_free_chan_resources(struct dma_chan *chan)
        ioat_chan->last_completion = ioat_chan->completion_addr = 0;
        ioat_chan->pending = 0;
        ioat_chan->dmacount = 0;
+       ioat_chan->desccount = 0;
        ioat_chan->watchdog_completion = 0;
        ioat_chan->last_compl_desc_addr_hw = 0;
        ioat_chan->watchdog_tcp_cookie =
@@ -974,11 +983,9 @@ static struct ioat_desc_sw *ioat_dma_get_next_descriptor(
        switch (ioat_chan->device->version) {
        case IOAT_VER_1_2:
                return ioat1_dma_get_next_descriptor(ioat_chan);
-               break;
        case IOAT_VER_2_0:
        case IOAT_VER_3_0:
                return ioat2_dma_get_next_descriptor(ioat_chan);
-               break;
        }
        return NULL;
 }
@@ -1335,8 +1342,9 @@ static void ioat_dma_start_null_desc(struct ioat_dma_chan *ioat_chan)
 
 static void ioat_dma_test_callback(void *dma_async_param)
 {
-       printk(KERN_ERR "ioatdma: ioat_dma_test_callback(%p)\n",
-               dma_async_param);
+       struct completion *cmp = dma_async_param;
+
+       complete(cmp);
 }
 
 /**
@@ -1353,6 +1361,7 @@ static int ioat_dma_self_test(struct ioatdma_device *device)
        dma_addr_t dma_dest, dma_src;
        dma_cookie_t cookie;
        int err = 0;
+       struct completion cmp;
 
        src = kzalloc(sizeof(u8) * IOAT_TEST_SIZE, GFP_KERNEL);
        if (!src)
@@ -1371,7 +1380,7 @@ static int ioat_dma_self_test(struct ioatdma_device *device)
        dma_chan = container_of(device->common.channels.next,
                                struct dma_chan,
                                device_node);
-       if (device->common.device_alloc_chan_resources(dma_chan, NULL) < 1) {
+       if (device->common.device_alloc_chan_resources(dma_chan) < 1) {
                dev_err(&device->pdev->dev,
                        "selftest cannot allocate chan resource\n");
                err = -ENODEV;
@@ -1392,8 +1401,9 @@ static int ioat_dma_self_test(struct ioatdma_device *device)
        }
 
        async_tx_ack(tx);
+       init_completion(&cmp);
        tx->callback = ioat_dma_test_callback;
-       tx->callback_param = (void *)0x8086;
+       tx->callback_param = &cmp;
        cookie = tx->tx_submit(tx);
        if (cookie < 0) {
                dev_err(&device->pdev->dev,
@@ -1402,7 +1412,8 @@ static int ioat_dma_self_test(struct ioatdma_device *device)
                goto free_resources;
        }
        device->common.device_issue_pending(dma_chan);
-       msleep(1);
+
+       wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000));
 
        if (device->common.device_is_tx_complete(dma_chan, cookie, NULL, NULL)
                                        != DMA_SUCCESS) {