OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [dma/] [ioat.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 * Intel I/OAT DMA Linux driver
3
 * Copyright(c) 2007 Intel Corporation.
4
 *
5
 * This program is free software; you can redistribute it and/or modify it
6
 * under the terms and conditions of the GNU General Public License,
7
 * version 2, as published by the Free Software Foundation.
8
 *
9
 * This program is distributed in the hope that it will be useful, but WITHOUT
10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12
 * more details.
13
 *
14
 * You should have received a copy of the GNU General Public License along with
15
 * this program; if not, write to the Free Software Foundation, Inc.,
16
 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17
 *
18
 * The full GNU General Public License is included in this distribution in
19
 * the file called "COPYING".
20
 *
21
 */
22
 
23
/*
24
 * This driver supports an Intel I/OAT DMA engine, which does asynchronous
25
 * copy operations.
26
 */
27
 
28
#include <linux/init.h>
29
#include <linux/module.h>
30
#include <linux/pci.h>
31
#include <linux/interrupt.h>
32
#include <linux/dca.h>
33
#include "ioatdma.h"
34
#include "ioatdma_registers.h"
35
#include "ioatdma_hw.h"
36
 
37
MODULE_VERSION(IOAT_DMA_VERSION);
38
MODULE_LICENSE("GPL");
39
MODULE_AUTHOR("Intel Corporation");
40
 
41
static struct pci_device_id ioat_pci_tbl[] = {
42
        /* I/OAT v1 platforms */
43
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT) },
44
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_CNB)  },
45
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SCNB) },
46
        { PCI_DEVICE(PCI_VENDOR_ID_UNISYS, PCI_DEVICE_ID_UNISYS_DMA_DIRECTOR) },
47
 
48
        /* I/OAT v2 platforms */
49
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB) },
50
        { 0, }
51
};
52
 
53
struct ioat_device {
54
        struct pci_dev          *pdev;
55
        void __iomem            *iobase;
56
        struct ioatdma_device   *dma;
57
        struct dca_provider     *dca;
58
};
59
 
60
static int __devinit ioat_probe(struct pci_dev *pdev,
61
                                const struct pci_device_id *id);
62
static void __devexit ioat_remove(struct pci_dev *pdev);
63
 
64
static int ioat_dca_enabled = 1;
65
module_param(ioat_dca_enabled, int, 0644);
66
MODULE_PARM_DESC(ioat_dca_enabled, "control support of dca service (default: 1)");
67
 
68
static int ioat_setup_functionality(struct pci_dev *pdev, void __iomem *iobase)
69
{
70
        struct ioat_device *device = pci_get_drvdata(pdev);
71
        u8 version;
72
        int err = 0;
73
 
74
        version = readb(iobase + IOAT_VER_OFFSET);
75
        switch (version) {
76
        case IOAT_VER_1_2:
77
                device->dma = ioat_dma_probe(pdev, iobase);
78
                if (device->dma && ioat_dca_enabled)
79
                        device->dca = ioat_dca_init(pdev, iobase);
80
                break;
81
        case IOAT_VER_2_0:
82
                device->dma = ioat_dma_probe(pdev, iobase);
83
                if (device->dma && ioat_dca_enabled)
84
                        device->dca = ioat2_dca_init(pdev, iobase);
85
                break;
86
        default:
87
                err = -ENODEV;
88
                break;
89
        }
90
        if (!device->dma)
91
                err = -ENODEV;
92
        return err;
93
}
94
 
95
static void ioat_shutdown_functionality(struct pci_dev *pdev)
96
{
97
        struct ioat_device *device = pci_get_drvdata(pdev);
98
 
99
        dev_err(&pdev->dev, "Removing dma and dca services\n");
100
        if (device->dca) {
101
                unregister_dca_provider(device->dca);
102
                free_dca_provider(device->dca);
103
                device->dca = NULL;
104
        }
105
 
106
        if (device->dma) {
107
                ioat_dma_remove(device->dma);
108
                device->dma = NULL;
109
        }
110
}
111
 
112
static struct pci_driver ioat_pci_driver = {
113
        .name           = "ioatdma",
114
        .id_table       = ioat_pci_tbl,
115
        .probe          = ioat_probe,
116
        .shutdown       = ioat_shutdown_functionality,
117
        .remove         = __devexit_p(ioat_remove),
118
};
119
 
120
static int __devinit ioat_probe(struct pci_dev *pdev,
121
                                const struct pci_device_id *id)
122
{
123
        void __iomem *iobase;
124
        struct ioat_device *device;
125
        unsigned long mmio_start, mmio_len;
126
        int err;
127
 
128
        err = pci_enable_device(pdev);
129
        if (err)
130
                goto err_enable_device;
131
 
132
        err = pci_request_regions(pdev, ioat_pci_driver.name);
133
        if (err)
134
                goto err_request_regions;
135
 
136
        err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
137
        if (err)
138
                err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
139
        if (err)
140
                goto err_set_dma_mask;
141
 
142
        err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
143
        if (err)
144
                err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
145
        if (err)
146
                goto err_set_dma_mask;
147
 
148
        mmio_start = pci_resource_start(pdev, 0);
149
        mmio_len = pci_resource_len(pdev, 0);
150
        iobase = ioremap(mmio_start, mmio_len);
151
        if (!iobase) {
152
                err = -ENOMEM;
153
                goto err_ioremap;
154
        }
155
 
156
        device = kzalloc(sizeof(*device), GFP_KERNEL);
157
        if (!device) {
158
                err = -ENOMEM;
159
                goto err_kzalloc;
160
        }
161
        device->pdev = pdev;
162
        pci_set_drvdata(pdev, device);
163
        device->iobase = iobase;
164
 
165
        pci_set_master(pdev);
166
 
167
        err = ioat_setup_functionality(pdev, iobase);
168
        if (err)
169
                goto err_version;
170
 
171
        return 0;
172
 
173
err_version:
174
        kfree(device);
175
err_kzalloc:
176
        iounmap(iobase);
177
err_ioremap:
178
err_set_dma_mask:
179
        pci_release_regions(pdev);
180
        pci_disable_device(pdev);
181
err_request_regions:
182
err_enable_device:
183
        return err;
184
}
185
 
186
/*
187
 * It is unsafe to remove this module: if removed while a requested
188
 * dma is outstanding, esp. from tcp, it is possible to hang while
189
 * waiting for something that will never finish.  However, if you're
190
 * feeling lucky, this usually works just fine.
191
 */
192
static void __devexit ioat_remove(struct pci_dev *pdev)
193
{
194
        struct ioat_device *device = pci_get_drvdata(pdev);
195
 
196
        ioat_shutdown_functionality(pdev);
197
 
198
        kfree(device);
199
}
200
 
201
static int __init ioat_init_module(void)
202
{
203
        return pci_register_driver(&ioat_pci_driver);
204
}
205
module_init(ioat_init_module);
206
 
207
static void __exit ioat_exit_module(void)
208
{
209
        pci_unregister_driver(&ioat_pci_driver);
210
}
211
module_exit(ioat_exit_module);

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.