/*
* Intel I/OAT DMA Linux driver
- * Copyright(c) 2004 - 2007 Intel Corporation.
+ * Copyright(c) 2004 - 2009 Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
ioat_chan->xfercap = xfercap;
ioat_chan->desccount = 0;
INIT_DELAYED_WORK(&ioat_chan->work, ioat_dma_chan_reset_part2);
- if (ioat_chan->device->version != IOAT_VER_1_2) {
- writel(IOAT_DCACTRL_CMPL_WRITE_ENABLE
- | IOAT_DMA_DCA_ANY_CPU,
- ioat_chan->reg_base + IOAT_DCACTRL_OFFSET);
- }
+ if (ioat_chan->device->version == IOAT_VER_2_0)
+ writel(IOAT_DCACTRL_CMPL_WRITE_ENABLE |
+ IOAT_DMA_DCA_ANY_CPU,
+ ioat_chan->reg_base + IOAT_DCACTRL_OFFSET);
+ else if (ioat_chan->device->version == IOAT_VER_3_0)
+ writel(IOAT_DMA_DCA_ANY_CPU,
+ ioat_chan->reg_base + IOAT_DCACTRL_OFFSET);
spin_lock_init(&ioat_chan->cleanup_lock);
spin_lock_init(&ioat_chan->desc_lock);
INIT_LIST_HEAD(&ioat_chan->free_desc);
* 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;
* up if the client is done with the descriptor
*/
if (async_tx_test_ack(&desc->async_tx)) {
- list_del(&desc->node);
- list_add_tail(&desc->node,
- &ioat_chan->free_desc);
+ list_move_tail(&desc->node,
+ &ioat_chan->free_desc);
} else
desc->async_tx.cookie = 0;
} else {
*/
#define IOAT_TEST_SIZE 2000
-DECLARE_COMPLETION(test_completion);
static void ioat_dma_test_callback(void *dma_async_param)
{
- printk(KERN_ERR "ioatdma: ioat_dma_test_callback(%p)\n",
- dma_async_param);
- complete(&test_completion);
+ struct completion *cmp = dma_async_param;
+
+ complete(cmp);
}
/**
dma_addr_t dma_dest, dma_src;
dma_cookie_t cookie;
int err = 0;
+ struct completion cmp;
+ unsigned long tmo;
src = kzalloc(sizeof(u8) * IOAT_TEST_SIZE, GFP_KERNEL);
if (!src)
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;
}
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,
}
device->common.device_issue_pending(dma_chan);
- wait_for_completion_timeout(&test_completion, msecs_to_jiffies(3000));
+ tmo = wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000));
- if (device->common.device_is_tx_complete(dma_chan, cookie, NULL, NULL)
+ if (tmo == 0 ||
+ device->common.device_is_tx_complete(dma_chan, cookie, NULL, NULL)
!= DMA_SUCCESS) {
dev_err(&device->pdev->dev,
"Self-test copy timed out, disabling\n");
" %d channels, device version 0x%02x, driver version %s\n",
device->common.chancnt, device->version, IOAT_DMA_VERSION);
+ if (!device->common.chancnt) {
+ dev_err(&device->pdev->dev,
+ "Intel(R) I/OAT DMA Engine problem found: "
+ "zero channels detected\n");
+ goto err_setup_interrupts;
+ }
+
err = ioat_dma_setup_interrupts(device);
if (err)
goto err_setup_interrupts;
struct dma_chan *chan, *_chan;
struct ioat_dma_chan *ioat_chan;
+ if (device->version != IOAT_VER_3_0)
+ cancel_delayed_work(&device->work);
+
ioat_dma_remove_interrupts(device);
dma_async_device_unregister(&device->common);
pci_release_regions(device->pdev);
pci_disable_device(device->pdev);
- if (device->version != IOAT_VER_3_0) {
- cancel_delayed_work(&device->work);
- }
-
list_for_each_entry_safe(chan, _chan,
&device->common.channels, device_node) {
ioat_chan = to_ioat_chan(chan);